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

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

使用复杂消息类型

您可使用其余消息类型做为字段类型。例如,假设你想在每一个SearchResponse消息中包含Result消息,您能够在同一个.proto中定义一个Result消息类型,而后在SearchResponse中指定一个Result类型的字段:java

message SearchResponse {
  repeated Result results = 1;
}

message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}复制代码

引入其余消息文件

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

你能够经过import引入其余的.proto文件:编程语言

import "myproject/other_protos.proto";复制代码

注意ui

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

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

importproto2proto3都适用编码

嵌套类型

您能够在其余消息类型中定义和使用消息类型,以下,Result消息定义在SearchResponse消息中:url

message SearchResponse {
  message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
  }
  repeated Result results = 1;
}复制代码

若是想重复使用Result,能够用Parent.Type的方式使用:spa

message AnotherResponse {
    SearchResponse.Result res = 1;
}复制代码

修改更新现有的消息格式

修改时要注意的规则:code

  1. 不要改变已经存在字段的标签
  2. 添加一个字段时,旧的消息将会收到这个字段的默认值
  3. 删除一个字段时,记得把该字段的标签添加到reserved
  4. int32,uint32,int64,uint64和bool都是兼容的。这意味着您能够将这些类型之一的字段更改成另外一个,而不会破坏前向或后向兼容性。转换过程至关于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

import "google/protobuf/any.proto";

message ErrorStatus {
  string message = 1;
  repeated google.protobuf.Any details = 2;
}复制代码

Oneof类型

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

定义oneof结构

message SampleMessage {
  oneof test_oneof {
    string name = 4;
    SubMessage sub_message = 9;
  }
}复制代码

oneof中能够是任意类型,除了repeated 字段

生成代码以后,也会对oneof字段生成getter,setter方法,可是出来的值须要你本身判断一下

Maps 类型

若是你要定义一个map,protobuf提供了一个语法:

map<key_type, value_type> map_field = N;复制代码

例如

map<string, Project> projects = 3;复制代码

注意事项

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

packages语法

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

package foo.bar;
message Open { ... }复制代码

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

message Foo {
  ...
  foo.bar.Open open = 1;
  ...
}复制代码
相关文章
相关标签/搜索