⼆.protobuf3数据类型
定义数据类型
⾸先让我们看⼀个⾮常简单的例⼦。假设您想要定义搜索请求消息格式,其中每个搜索请求都有⼀个查询字符串、您感兴趣的特定结果页⾯以及每页的结果数量。这是⽤来定义消息类型的.proto⽂件。
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
⽂件的第⼀⾏指定您正在使⽤proto 3语法:如果不这样做,协议缓冲区编译器将假设您正在使⽤proto 2。这必须是⽂件的第⼀个⾮空的⾮注释⾏。
SearchRequest消息定义指定了三个字段(名称/值对),每⼀个字段对应于要包含在这种类型的消息中的数据。每个字段都有⼀个名称和⼀个类型。
指定字段类型
在上例中,所有字段都是标量类型:两个整数(page_number和result_per_page)和⼀个字符串(query)。但是,您也可以为字段指定复合类型,包括枚举和其他消息类型。
分配字段编号
如您所见,消息定义中的每个字段都有⼀个唯⼀的编号。这些字段编号⽤于以⼆进制格式标识您的字段,⼀旦您的消息类型被使⽤,就不应该被更改。请注意,1到15范围内的字段编号需要⼀个字节来编码,包括字段编号和字段类型(您可以在协议缓冲区编码中到更多信息)。16到2047范围内的字段编号需要两个字节。因此,您应该为经常出现的消息元素保留数字1到15。记住为将来可能添加的频繁出现的元素留出⼀些空间。
您可以指定的最⼩字段编号为1,最⼤字段编号为229 - 1,即536,870,911。但是不能使⽤数字19000到19999 ( FieldDescriptor::kFirstReservedNumber 到FieldDescriptor::kLastReservedNumber),因为它们是为协议缓冲区实现⽽保留的-如果您在
.
proto⽂件中使⽤这些保留的数字之⼀,协议缓冲区编译器就会报错。同样,您也不能使⽤任何保留字段。
指定字段规则
消息字段可以是以下字段之⼀:
singular: 可以有零个或其中⼀个字段(但不超过⼀个)。
repeated: 该字段可以重复任意次数(包括零次)。重复值的顺序将被保留。
在proto 3中,可扩展的repeated字段为数字类型的默认编码。
您可以在协议缓冲区编码中到更多关于打包编码的信息。
添加更多消息类型
可以在单个.proto中定义多种消息类型。如果您要定义多个相关消息,这很有⽤——例如,如果您想定义与搜索响应消息类型相对应的回复消息格式,可以将其添加到该.proto中:
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
message SearchResponse {
...
}
添加注释
为你的.proto 添加注释,使⽤ C/C++风格的 // 或者 /* ... */ 语法.
/* SearchRequest represents a search query, with pagination options to
字符串是什么字段类型* indicate which results to include in the response. */
message SearchRequest {
string query = 1;
int32 page_number = 2;  // Which page number do we want?
int32 result_per_page = 3;  // Number of results to return per page.
}
保留字段
如果通过完全删除某个字段或对其进⾏注释来更新消息类型,将来的⽤户可以在对该类型进⾏⾃⼰的更新时重⽤该字段编号。如果他们以后加载旧版本的相同.proto⽂件,这可能会导致严重的问题,包括数据损坏、隐私漏洞等。确保不会发⽣这种情况的解决⽅案是指定已删除字段的字段编号(and/or名称,这也可能导致JSON序列化问题)是保留的。如果将来有任何⽤户试图使⽤这些字段标识符,协议缓冲区编译器会报错。
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
请注意,不能在同⼀保留语句中混合字段名和字段编号。
从.proto⽂件中⽣成了什么?
在.proto上运⾏协议缓冲区编译器时,编译器⽤您指定的编程语⾔⽣成代码,您需要使⽤您在⽂件中描述的消息类型,包括获取和设置字段值,将消息序列化为输出流,以及从输⼊流解析消息。
对于C++,编译器会从每个 .proto⽂件⽣成⼀个 .h and .cc⽂件, ⽂件中描述的每种消息类型都有⼀个类。
对于Java,编译器为每个消息类型⽣成⼀个Java⽂件,其中包括每个类的定义,以及⽤于创建消息类实例的特殊构建器类。
Python有点不同,Python编译器⽣成⼀个模块,其中包含中每种消息类型的静态描述符,然后与元类⼀起使⽤,在运⾏时创建必要的Python数据访问类。
对于Go, 编译器⽣成⼀个.pb.go⽂件,其中包含⽂件中每种消息类型的类型。
对于Ruby, 编译器⽣成⼀个.rb⽂件带有包含消息类型的Ruby模块。
对于Objective-C, 编译器为每个.proto⽂件中⽣成⼀个pbobjc.h和pbobjc.m⽂件,⽂件中描述的每种消息类型都有⼀个类。
对于C#, 编译器为每个.proto⽂件⽣成⼀个.cs⽂件,⽂件中描述的每种消息类型都有⼀个类。
通过所选语⾔的教程( proto 3版本即将推出),您可以了解关于为每种语⾔使⽤API的更多信息。有关更多的API细节,请参见相关的API参考( proto 3版本也即将推出)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。