protobuf文件必须以以下结构来书写
限定修饰符 数据类型 字段名称 = 字段默认值
例如 :optional(限定修饰符) string(数据类型) account(名称) = 1(默认值);
①限定修饰符:①限定修饰符:
限定修饰符包含 required\optional\repeated
Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。
Optional:表示是一个可选字段,可选对于发送方可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。—因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。
Repeated:表示该字段可以包含[0,N]个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。
②数据类型:
|
N 表示打包的字节并不是固定。而是根据数据的大小或者长度。
例如int32,如果数值比较小,在0~127时,使用一个字节打包。
关于枚举的打包方式和uint32相同。
关于message,类似于C语言中的结构包含另外一个结构作为数据成员一样。
关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.
③字段名称:
字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。
protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.
注意:
1)关于import
protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。
2)关于package
避免名称冲突,可以给每个文件指定一个package名称,对于java解析为java中的包。对于C++则解析为名称空间。
3)关于message
支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息。
关于enum
枚举的定义和C#相同,但是有一些限制。
枚举值必须大于等于0的整数。
使用分号(;)分隔枚举变量
4)同一个meaage里默认值不能设置为相同的值否则会报错
测试proto如下
package test.pro;
message Test {
optional bool test =1;
required double test1 = 2;
optional float test2 =3;
optional int32 test3 = 4;
optional uint32 test4 =5;
optional int64 test5 = 6;
optional uint64 test6 =7;
optional sint32 test7 = 8;
optional sint64 test8 =9;
optional fixed32 test9 = 10;
optional fixed64 test10 =11;
optional sfixed32 test11 = 12;
optional sfixed64 test12 =13;
optional string test13 = 14;
optional bytes test14 =15;
enum TestEnum
{
testEnum1 = 1;
testEnum2 = 2;
testEnum3 = 3;
testEnum4 = 4;
}
}
import "proto/test.pro";
message Test1
{
required test.pro.Test.TestEnum testEnum=20;
}
该测试文件同样发布在上一篇博文的github中
要搭配我上一篇博文完成的编译器配合使用或者有大佬用自己完成的编译器也行
如何编译请查看我的上一篇博文https://blog.csdn.net/weixin_39637610/article/details/87900274