protobuf

总的来说,proto3 比 proto2 支持更多语言但 更简洁。去掉了一些复杂的语法和特性,更强调约定而弱化语法。如果是首次使用 Protobuf ,建议使用 proto3 。

1. 在第一行非空白非注释行,必须写:

syntax = “proto3”;

2. 字段规则移除了 “required”,”optional”;

在 proto2 中 required 也是不推荐使用的。proto3 直接从语法层面上移除了 required 规则。其实可以做的更彻底,把所有字段规则描述都撤销,原来的 repeated 改为在类型或字段名后加一对中括号。这样是不是更简洁?

3. “repeated”字段默认采用 packed 编码;

在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式。

4. 语言增加 Go. Ruby. JavaNano 支持;

5. 移除了 default 选项;

在 proto2 中,可以使用 default 选项为某一字段指定默认值。在 proto3 中,字段的默认值只能根据字段类型由系统决定。也就是说,默认值全部是约定好的,而不再提供指定默认值的语法。

在字段被设置为默认值的时候,该字段不会被序列化。这样可以节省空间,提高效率。

但这样就无法区分某字段是根本没赋值,还是赋值了默认值。这在 proto3 中问题不大,但在 proto2 中会有问题。

比如,在更新协议的时候使用 default 选项为某个字段指定了一个与原来不同的默认值,旧代码获取到的该字段的值会与新代码不一样。

另一个重约定而弱语法的例子是 go 语言里的公共/私有对象。Go 语言约定,首字母大写的为公共对象,否则为私有对象。所以在 Go 语言中是没有 public. private 这样的语法的。

6. 枚举类型的第一个字段必须为 0 ;

这也是一个约定。

7. 移除了对分组的支持;

8. v3.12 扩展增加optional 命令行 –experimental_allow_proto3_optional

9. 类型

Mobile Preview