Protobuf 属性解释
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}
一个 proto 文件主要包含 package 定义、message 定义和属性定义三个部分,还有一些可选项。
文件的第一行指定了你正在使用 proto3 语法:如果你没有指定这个,编译器会使用 proto2。这个指定语法行必须是文件的非空非注释的第一个行。
1.1 定义 package
Package 在 c++中对应 namespace。
对于 Java,包声明符会变为 java 的一个包,除非在.proto 文件中提供了一个明确有 java_package。
1.2 定义 message
Message 在 C++中对应 class。Message 中定义的全部属性在 class 中全部为 private 的。
Message 的嵌套使用可以嵌套定义,也可以采用先定义再使用的方式。
Message 的定义末尾可以采用 java 方式在不加“;”,也可以采用 C++定义方式在末尾加上“;”,这两种方式都兼容,建议采用 java 定义方式。
向.proto 文件添加注释,可以使用 C/C++/java 风格的双斜杠(//) 语法格式。
1.3 定义属性
属性定义分为四部分:标注+类型+属性名+属性顺序号+[默认值],其示意如下所示。
<table border="1" cellpadding="0" cellspacing="0"><tbody><tr><td><p><strong><em>标注</em></strong></p></td><td><p><strong><em>类型</em></strong></p></td><td><p><strong><em>属性名</em></strong></p></td><td><p><strong><em>属性顺序号</em></strong></p></td><td><p><em>[</em><em>默认值</em><em>]</em></p></td></tr><tr><td><p><em>required</em></p></td><td><p><em>string</em></p></td><td><p><em>name</em></p></td><td><p><em>= 1</em></p></td><td><p><em>[default=””];</em></p></td></tr></tbody></table>
其中属性名与 C++和 java 语言类似,不再解释;下面分别对标注、类型和属性顺序号加以详细介绍。
其中包名和消息名以及其中变量名均采用 java 的命名规则——驼峰式命名法,驼峰式命名法规则见附件 1。
1.3.1 标注
标注包括“required”、“optional”、“repeated”三种,其中
required 表示该属性为必选属性,否则对应的 message“未初始化”,debug 模式下导致断言,release 模式下解析失败;
optional 表示该属性为可选属性,不指定,使用默认值(int 或者 char 数据类型默认为 0,string 默认为空,bool 默认为 false,嵌套 message 默认为构造,枚举则为第一个)
repeated 表示该属性为重复字段,可看作是动态数组,类似于 C++中的 vector。
如果为 optional 属性,发送端没有包含该属性,则接收端在解析式采用默认值。对于默认值,如果已设置默认值,则采用默认值,如果未设置,则类型特定的默认值为使用,例如 string 的默认值为””。
1.3.2 类型
Protobuf 的属性基本包含了 c++需要的所有基本属性类型。
<table border="1" cellpadding="1" cellspacing="1"><tbody><tr><td><p><strong>protobuf</strong><strong>属性</strong></p></td><td><p><strong>C++</strong><strong>属性</strong></p></td><td><p><strong>java</strong><strong>属性</strong></p></td><td><p><strong>备注</strong></p></td></tr><tr><td><p>double</p></td><td><p>double</p></td><td><p>double</p></td><td><p>固定 8 个字节</p></td></tr><tr><td><p>float</p></td><td><p>float</p></td><td><p>float</p></td><td><p>固定 4 个字节</p></td></tr><tr><td><p>int32</p></td><td><p>int32</p></td><td><p>int32</p></td><td><p>使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用 sint32</p></td></tr><tr><td><p>int64</p></td><td><p>int64</p></td><td><p>int64</p></td><td><p>使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用 sint64</p></td></tr><tr><td><p>uint32</p></td><td><p>uint32</p></td><td><p>int</p></td><td><p>使用变长编码</p></td></tr><tr><td><p>uint64</p></td><td><p>uint64</p></td><td><p>long</p></td><td><p>使用变长编码</p></td></tr><tr><td><p>sint32</p></td><td><p>int32</p></td><td><p>int</p></td><td><p>采用 zigzag 压缩,对负数编码效率比 int32 高</p></td></tr><tr><td><p>sint64</p></td><td><p>int64</p></td><td><p>long</p></td><td><p>采用 zigzag 压缩,对负数编码效率比 int64 高</p></td></tr><tr><td><p>fixed32</p></td><td><p>uint32</p></td><td><p>int</p></td><td><p>总是 4 字节,如果数据>2^28,编码效率高于 unit32</p></td></tr><tr><td><p>fixed64</p></td><td><p>uint64</p></td><td><p>long</p></td><td><p>总是 8 字节,如果数据>2^56,编码效率高于 unit32</p></td></tr><tr><td><p>sfixed32</p></td><td><p>int32</p></td><td><p>int</p></td><td><p>总是 4 字节</p></td></tr><tr><td><p>sfixed64</p></td><td><p>int64</p></td><td><p>long</p></td><td><p>总是 8 字节</p></td></tr><tr><td><p>bool</p></td><td><p>bool</p></td><td><p>boolean</p></td><td><p></p></td></tr><tr><td><p>string</p></td><td><p>string</p></td><td><p>String</p></td><td><p>一个字符串必须是 utf-8 编码或者 7-bit 的 ascii 编码的文本</p></td></tr><tr><td><p>bytes</p></td><td><p>string</p></td><td><p>ByteString</p></td><td><p>可能包含任意顺序的字节数据</p></td></tr></tbody></tab
le>
1.3.3 Union 类型定义
Protobuf 没有提供 union 类型,如果希望使用 union 类型,可以采用 enum 和 optional 属性定义的方式。
例如,如果已经定义了 Foo、Bar、Baz 等 message,则可以采用如下定义。
message OneMessage {
enum Type { FOO = 1; BAR = 2; BAZ = 3; }
// 标识要填写的字段,必填
required Type type = 1;
// 将填写以下内容之一,可选
optional Foo foo = 2;
optional Bar bar = 3;
optional Baz baz = 4;
}
1.3.4?message 类型定义
=========================
Protobuf 中定义一个数据结构需要用到关键字 message,这一点和 Java 的 class,Go 语言中的 struct 类似。
评论