|
官网
官网小栗子
syntax = "proto2";
package tutorial;
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}如你所见protobuf的语法类似于C++或者Java。
protocol buf的文件后缀为 .proto,该文件从一个package的声明开始,一个package类似于C++一个namespace。事实上,这个package的名称,就是生成的c++中的namespace。
定义完package就是定义message了,一个message是一系列type的集合,在protocol buf中有一系列可用的基础类型,包括 bool, int32, float, double和string。当然你可以增加一些使用现有的type组合一些较为高级的struct。如上面的person message就包含了PhoneNumber message,AddressBook message又包含了Person message。你也可以message中嵌套定义其他message,就像PhoneNumber type定义在Person中。你也可以定于enum类型。如果你希望改类型只能初始化为预定于的值之一(类似于c++ enum)。如例子中的PhoneType 只希望是 MOBILE,HOME, WORK其中之一。
可以注意到mesage中的元素上有“=1”,“=2”的标签。这些标签主要用于二进制的编码使用。当标签的数超过15时,编码时会比1-15多一个字节,所以,我们可以对常用的元素打上1-15的标签,不常用的元素打上15以上的标签,repeate中的每个元素都需要重新编码,所以,最好对repeate元素打上1-15的标签。
每个代码块都需要使用一下其中之一进行声明。
- optional:该关键词表示,对该区域设置或者不设置都是合法的。如果没有设置该区域,则会使用默认值。对于简单类型是可以设置默认值的,例如例子中的optional PhoneType type = 2 [default = HOME]; 如果没有显示去指定默认值,系统会将数值设置为0,字符串设置成空字符串,bool设置为false。如果是是一个嵌入组合类型,默认值一般会使用默认初始化函数去初始化,访问没有被显示初始化的optional或者require的变量时,返回其默认值。
- repeated:被该关键词修饰的变量可以被重复任意的次数(包括0次),重复的数字顺序将被保留在protocol buffer中,可以将repeate的区域理解为动态数组。
- require:被该关键词修饰的变量必须提供具体数值去初始化,否则该变量将被标识为"uninitialized",如果在libprotobuf的debug模式下编译,如果有uninitialized的变量则会报错。在优化的编译中,这个check会被跳过,message会被强制编码。但是在解析没有初始化的message的时候会报报错(parse 函数会返回false)。除此之外,optinal关键词和require完全一致。
|
|