Protobuf 的 proto3 与 proto2 的区别

转载 2017年07月29日 11:57:16

http://www.cppblog.com/tx7do/archive/2016/11/17/214414.html


转载自:https://solicomo.com/network-dev/protobuf-proto3-vs-proto2.html

这是一篇学习笔记。在粗略的看了 Protobuf 的文档中关于 proto2 和 proto3 的说明后,记录下了几点 proto3 区别于 proto2 的地方。

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

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

    syntax = "proto3";

  2. 字段规则移除了 “required”,并把 “optional” 改名为 “singular”;

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

  3. 语言增加 Go、Ruby、JavaNano 支持;

  4. 移除了 default 选项;

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

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

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

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

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

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

    这也是一个约定。

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

    分组的功能完全可以用消息嵌套的方式来实现,并且更清晰。在 proto2 中已经把分组语法标注为『过期』了。这次也算清理垃圾了。

  7. 旧代码在解析新增字段时,会把不认识的字段丢弃,再序列化后新增的字段就没了;

    在 proto2 中,旧代码虽然会忽视不认识的新增字段,但并不会将其丢弃,再序列化的时候那些字段会被原样保留。

    我觉得还是 proto2 的处理方式更好一些。能尽量保持兼容性和扩展能力,或许实现起来也更简单。proto3 现在的处理方式,没有带来明显的好处,但丢掉了部分兼容性和灵活性。

  8. 移除了对扩展的支持,新增了 Any 类型;

    Any 类型是用来替代 proto2 中的扩展的。目前还在开发中。

    proto2 中的扩展特性很像 Swift 语言中的扩展。理解起来有点困难,使用起来更是会带来不少混乱。

    相比之下,proto3 中新增的 Any 类型有点想 C/C++ 中的 void* ,好理解,使用起来逻辑也更清晰。

  9. 增加了 JSON 映射特性;

    语言的活力来自于与时俱进。当前,JSON 的流行有其充分的理由。很多『现代化』的语言都内置了对 JSON 的支持,比如 Go、PHP 等。而 C++ 这种看似保罗万象的学院派语言,因循守旧、故步自封,以致于现出了式微的苗条。


Protobuf3 google protobuf

Protocol Buffers是一个跨语言、跨平台的具有可扩展机制的序列化数据工具。也就是说,我在ubuntu下用python语言序列化一个对象,并使用http协议传输到使用java语言的andro...
  • dodouaj
  • dodouaj
  • 2016年01月08日 18:53
  • 12263

多版本protobuf(protoc.exe),支持proto、proto2、proto3

  • 2016年12月22日 09:54
  • 1.59MB
  • 下载

Protobuf 的 proto3 与 proto2 的区别

本文转自:https://solicomo.com/network-dev/protobuf-proto3-vs-proto2.html 总的来说,proto3 比 proto2 支持更多语言但...
  • liujiayu2
  • liujiayu2
  • 2017年09月04日 14:51
  • 328

Google Protobuf 3版本介绍

转:http://www.cppblog.com/sunicdavy/archive/2016/01/25/212739.html Proto3的语法变化 语法标记 这个版本的pro...
  • u014695188
  • u014695188
  • 2017年01月11日 11:39
  • 1959

Protobuf3语言指南

定义一个消息类型 指定字段类型 分配标识号 指定字段规则 添加更多消息类型 添加注释 保留标识符(Reserved) 从.proto文件生成了什么? 标量数值类型 默认值 枚举 使用其他消息类型 ...
  • u011518120
  • u011518120
  • 2017年01月25日 22:14
  • 18563

Protobuf3 系列二 定义复杂的proto文件

定义复杂的对象这是Protobuf3的系列二: 如何在protobuf中定义更复杂的对象proto文件除了定义string, int等基础对象外(protobuf的基础数据结构和Java变量的对应关系...
  • hry2015
  • hry2015
  • 2017年04月25日 19:56
  • 5639

protobuf引入不同包下的proto文件

1、引入部分 package com.road.ddt.proto.game; option java_package = "com.road.ddt.pb.game"; option java...
  • u010366135
  • u010366135
  • 2017年02月06日 15:22
  • 2391

Protobuf简单使用及其抓包分析

早之前就用过Google的Protobuf做数据编码,一直没有深入理解其中的原理,最近做了一次通讯抓包,发现其中很多Protobuf编码的数据包,于是决定分析一下其中的数据包及其编码。一、Protob...
  • wangqiuyun
  • wangqiuyun
  • 2014年12月24日 11:36
  • 24654

protobuf嵌套类操作实例

protobuf类进行嵌套时,协议描述如下: /* 客户端拉取消息请求包 */ message Secret_Get_Req { required uint32 version = 1; ...
  • dreamvyps
  • dreamvyps
  • 2014年07月15日 20:37
  • 5215

protobuf 中的嵌套消息的使用

之前已经介绍了protobuf的简单的使用,不过还留下了一个问题,那就是之前主要介绍的都是对简单数据的赋值,简单数据直接采用set_xx()即可,但是如果不是简单变量而是自定义的复合类型变量,就没有简...
  • u010739551
  • u010739551
  • 2015年04月22日 00:24
  • 4614
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Protobuf 的 proto3 与 proto2 的区别
举报原因:
原因补充:

(最多只允许输入30个字)