写点什么

Protobuf 属性解释

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:2497 字

    阅读完需:约 8 分钟

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


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


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 类似。

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Protobuf 属性解释