当前位置:   article > 正文

【Protobuf速成指南】Message中如何定义“数组”?_protobuf 数组

protobuf 数组

2.0

 本系列文章将通过对通讯录项目的不断完善,带大家由浅入深的学习Protobuf的使用。这是Contacts的2.0版本,在这篇文章中将带大家正式开始编写通讯录,并进一步学习Protobuf的语法

一、字段规则

1.1 规则

消息的每个字段可以用下面的规则进行修饰:

  • singular:消息中可以包含该字段零次或一次。proto3语法中,字段默认使用该规则 (注:出现0次的字段如果没有默认值,就不会被序列化到消息中)
  • repeated:消息中可以包含该字段任意多次(包括零次),并会按先顺序保存。可以理解为定义了一个数组

1.2 改进

我们现在改进1.0版的通讯录,增加一个规则为 repeated 的 phone_number字段

syntax = "proto3";
package contact2;

message PeopleInfo{
    string name = 1;
    int32 age = 2;
    repeated string phone = 3;  // 相当于一个 string 数组了
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

下面增加一点难度,将phone类型也定义为一个message

1.3 消息类型作为字段类型

  • Protobuf是支持嵌套定义message的

    message PeopleInfo{
        string name = 1;
        int32 age = 2;
        message Phone{   // 在不同的message中唯一编号是可以重复的
            string number = 1;
            string tyepe = 2;
        }
        repeated Phone phone = 3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • import 其他proto文件中定义的message类型

    // phone.proto中的内容
    syntax = "proto3";
    package phone;
    
    message Phone{
        string number = 1;
        string tyepe = 2;
    }
    
    // contact2.proto
    syntax = "proto3";
    package contact2;
    
    import "phone.proto";
    
    message PeopleInfo{
        string name = 1;
        int32 age = 2;
        // phone.xxx 表示在phonen包中
        // 如果 Phone 没有定义在任何包内,则可以省略
        repeated phone.Phone phone = 3; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

 使用Vscode的时候,你可能会看到如下的报错,这是Vscode插件的问题,我们语法没有出错,我们可以正常编译没有问题。

image-20230606152343975

【注】:proto3可以导入proto2的消息类型并使用它,反之亦然

最终 contact.proto 文件内容如下:

syntax = "proto3";
package contact2;

message PeopleInfo{
    string name = 1;
    int32 age = 2;
    message Phone{   
        string number = 1;
        string tyepe = 2;
    }
    repeated Phone phone = 3;
}

message Contact{
    repeated PeopleInfo contact = 1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

二、repeated字段使用方式

编译后我们发现生成了两个类,这也是符合我们预期的image-20230606153257356

 由于Phone消息是嵌套定义在PeopleInfo消息中的,因此生成的class名前面有一个PeopleInfo_

编译后,编译器为 repeated phone 额外提供了这些接口,部分如下:

inline int PeopleInfo::phone_size() const {...}// 返回数组元素个数

inline ::contact2::PeopleInfo_Phone* PeopleInfo::mutable_phone(int index) {...}        // 相当于返回 &phone[index]

inline const ::contact2::PeopleInfo_Phone& PeopleInfo::phone(int index) const {...}  // 相当于 phone[index]

inline ::contact2::PeopleInfo_Phone* PeopleInfo::add_phone() {}
// 添加一个新的Phone对象到PeopleInfo中的phones数组中,并返回一个可变的(mutable)指向新添加的对象的指针。我们可以通过该指针修改该新对象的内容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

三、Contact2.0

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/430315?site
推荐阅读
相关标签