Protobuf 的 proto3 与 proto2 的区别

 

On 2015-07-17 19:16:00 By Soli

 

Protobuf 的 proto3 与 proto2 的区别

这是一篇学习笔记。在粗略的看了 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++ 这种看似保罗万象的学院派语言,因循守旧、故步自封,以致于现出了式微的苗条。

转: Protobuf 的 proto3 与 proto2 的区别的更多相关文章

  1. 使用protobuf (proto3, C++和go语言)

    在这里,我先讲述C++使用protobuf,之后,会补充使用go语言使用protobuf. 使用protobuf需要有如下步骤: 在.proto文件中定义消息(message)格式. 使用protob ...

  2. hbase协处理器编码实例

    Observer协处理器通常在一个特定的事件(诸如Get或Put)之前或之后发生,相当于RDBMS中的触发器.Endpoint协处理器则类似于RDBMS中的存储过程,因为它可以让你在RegionSer ...

  3. protobuf入门教程

    1.简介和安装 2.消息类型 3.proto3 与 proto2 的区别 4.常用序列化/反序列化接口 5.repeated限定修饰符 6.枚举(enum).包(package) 7.导入定义(imp ...

  4. google protobuf序列化原理解析 (PHP示例)

    一.简介 Protocol Buffers是谷歌定义的一种跨语言.跨平台.可扩展的数据传输及存储的协议,因为将字段协议分别放在传输两端,传输数据中只包含数据本身,不需要包含字段说明,所以传输数据量小, ...

  5. Protobuf 小试牛刀

    本文以PHP为例. 环境: CentOS 6.8 proto 3.8 PHP 7.1.12 PHP protobuf扩展 3.8.0 go1.12.5 linux/amd64 本文示例仓库地址: ht ...

  6. Protobuf协议应用干货

    Protobuf应用广泛,尤其作为网络通讯协议最为普遍.本文将详细描述几个让人眼前一亮的protobuf协议设计,对准备应用或已经应用protobuf的开发者会有所启发,甚至可以直接拿过去用. 这里描 ...

  7. 深入理解 ProtoBuf 原理与工程实践(概述)

    ProtoBuf 作为一种跨平台.语言无关.可扩展的序列化结构数据的方法,已广泛应用于网络数据交换及存储.随着互联网的发展,系统的异构性会愈发突出,跨语言的需求会愈加明显,同时 gRPC 也大有取代R ...

  8. ProtoBuf 与 gRPC

    用 Protobuf 很久了,但是一直觉得很简单,所以就没有做一个总结,今天想尝试一下 gRPC,顺带就一起总结一下.ProtoBuf 是个老同志了,应该是 2010 的时候发布的,然后被广泛使用,目 ...

  9. golang 使用 protobuf 的教程

    1.下载protobuf的编译器protoc 地址: https://github.com/google/protobuf/releases window:    下载: protoc-3.3.0-w ...

随机推荐

  1. spi 10方式编写

    //第一个CS变低的时候要sclk为高电平,第一个跳变沿进行赋值 module spi(input clk,input rst_n,output reg sclk,output reg cs,outp ...

  2. 时钟周期,CPU周期,指令周期,CPU时间片

    从小到大来说:时钟周期,CPU周期,指令周期,CPU时间片 时钟周期:一个脉冲需要的时间,频率的倒数 CPU周期:读取一个指令节所需的时间 指令周期:读取并执行完一个指令所需的时间 CPU时间片:CP ...

  3. GJM : 数据结构学习笔记

    --------------------------数据结构 --------------------数据结构分 线性数据结构给非线性数据结构 数据和结合 线性表(顺序存储方式)特点:有且仅有一个开始 ...

  4. SharePoint Framework:下一代开发方式

    SharePoint Framework(SPFx),是页面 和Webpart的模型,完全支持本地开发(即完全可以脱离SharPoint环境在本地进行开发),听起来是不是很高级呢,早期SharePoi ...

  5. 对CVE-2014-6271 [破壳漏洞] 的一次不太深入的跟踪

    @firtst:有些事,该你遇到的始终会遇到!2013年,Struts2远程代码执行漏洞闹的满城风雨时,当时还对此一无所知:2014年4月,HeartBleed掀起波涛汹涌时,较快对此予以关注,晚上跑 ...

  6. reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.

     album = responseObject[@"album"]; 是我将一个字典直接赋值给了对象 改为如下即可 [album setValuesForKeysWithDicti ...

  7. weblogic安装注意事项_linux

    ➠更多技术干货请戳:听云博客 一.安装过程:参考“weblogic安装截屏(linux)” 注意事项:安装weblogic时,需要注意以下两点: 1.首先在安装目录下创建weblogic12文件夹 如 ...

  8. iOS--xuer(registration)

    这个登录页面包含了自适应屏幕的大小,数字用户登录键盘是数字键盘.隐藏键盘.隐藏密码等等. ViewController.h #import <UIKit/UIKit.h> #import ...

  9. OC 类别与扩展(匿名类别)

    OC 类别与扩展(匿名类别) 类别(Categroy): 又称为扩展类,在类的原基础上扩展方法,且不可添加变量,如果扩展的方法与原始类中的方法相同,则会隐藏原始方法,且不可在扩展方法中通过super调 ...

  10. Android屏幕适配总结

    一.首先需要明白的几个概念 1.屏幕尺寸:也就是我们平常所说的某某手机几寸屏.比如苹果的4.7寸, 荣耀6的5.5寸.这里说的寸是英寸(1 英寸 = 2.54 厘米). 计算方法:屏幕尺寸=对角先尺寸 ...