• Protocol Buffers学习(4):更多消息类型


    介绍一下消息的不同类型和引用

    使用复杂消息类型

    您可以使用其他消息类型作为字段类型。例如,假设你想在每个SearchResponse消息中包含Result消息,您可以在同一个.proto中定义一个Result消息类型,然后在SearchResponse中指定一个Result类型的字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    message SearchResponse {
    repeated Result results = 1;
    }

    message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
    }

    引入其他消息文件

    在上述示例中,Result消息类型与SearchResponse在相同的文件中定义, 如果要使用的消息类型已经在另一个.proto文件中定义了怎么解决呢?

    你可以通过import引入其他的.proto文件:

    1
    import "myproject/other_protos.proto";

    注意

    接上边的例子,假如a.proto引入了b.proto,但是b.proto更换了位置,路径变成了test/b.proto(随便举例),我们有两种解决办法:

    1. 修改a.proto中的import语句,直接import "test/b.proto"
    2. b.proto文件原来的位置,创建一个b.proto文件,文件内容为import public "test/b.proto",就可以了

    importproto2proto3都适用

    嵌套类型

    您可以在其他消息类型中定义和使用消息类型,如下,Result消息定义在SearchResponse消息中:

    1
    2
    3
    4
    5
    6
    7
    8
    message SearchResponse {
    message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
    }
    repeated Result results = 1;
    }

    如果想重复使用Result,可以用Parent.Type的方式使用:

    1
    2
    3
    message AnotherResponse {
    SearchResponse.Result res = 1;
    }

    修改更新现有的消息格式

    修改时要注意的规则:

    1. 不要改变已经存在字段的标签
    2. 添加一个字段时,旧的消息将会收到这个字段的默认值
    3. 删除一个字段时,记得把该字段的标签添加到reserved
    4. int32,uint32,int64,uint64和bool都是兼容的。这意味着您可以将这些类型之一的字段更改为另一个,而不会破坏前向或后向兼容性。转 大专栏  Protocol Buffers学习(4):更多消息类型换过程相当于C ++中将该数字转换为该类型(例如,如果将64位数字读为int32, 它将被截断到32位)
    5. sint32和sint64相互兼容,但与其他整数类型不兼容
    6. 只要字节是有效的UTF-8,字符串和字节是兼容的
    7. 嵌套消息(message)与包含消息的编码版本的字节(bytes)兼容【表述不清,欢迎大家评论指正】
    8. fixed32与sfixed32兼容,fixed64与sfixed64兼容
    9. 枚举兼容int32,uint32,int64和uint64(请注意,如果值不合适,那么值将被截断)。 但是请注意,客户端代码可以在消息反序列化时对它们进行不同的处理:例如,消息中将保留无法识别的proto3枚举类型,但是当消息反序列化时,如何处理和使用的编程语言相关。 Int字段始终保持其值

    Any类型

    any类型时谷歌protobuf内置的一个类型,通用类型,使用的时候需要导入google/protbuf/any.proto

    1
    2
    3
    4
    5
    6
    import "google/protobuf/any.proto";

    message ErrorStatus {
    string message = 1;
    repeated google.protobuf.Any details = 2;
    }

    Oneof类型

    Oneof结构中有多个字段,但是同一时刻只有一个字段生效

    定义oneof结构

    1
    2
    3
    4
    5
    6
    message SampleMessage {
    oneof test_oneof {
    string name = 4;
    SubMessage sub_message = 9;
    }
    }

    oneof中可以是任意类型,除了repeated 字段

    生成代码之后,也会对oneof字段生成getter,setter方法,但是出来的值需要你自己判断一下

    Maps 类型

    如果你要定义一个map,protobuf提供了一个语法:

    1
    map<key_type, value_type> map_field = N;

    例如

    1
    map<string, Project> projects = 3;

    注意事项

    • Map字段不能是repeated
    • Map中的集合是无序的
    • .proto文件生成时,map按key排序
    • 解析或者合并时,后边的会覆盖前边的

    packages语法

    你可以添加一个可选标识package.proto文件中。用来防止命名冲突

    1
    2
    package foo.bar;
    message Open { ... }

    在使用这条消息的时候需要加上package名字

    1
    2
    3
    4
    5
    message Foo {
    ...
    foo.bar.Open open = 1;
    ...
    }
  • 相关阅读:
    python中的面向对象编程
    python global vs nonlocal (2)
    python3 nonlocal vs global
    poj蚂蚁问题
    C/C++ static vs global
    砝码问题
    Wythoff's game
    C++中的::operator new, ::operator delete
    客户信息表 自我汇总 待确认
    Oracle Savepoint
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12037794.html
Copyright © 2020-2023  润新知