Google Protobuf 3版本介绍

本文深入探讨了Google Protobuf 3版本,这是一个强大的数据序列化工具,广泛用于网络通信和数据存储。它提供高效的二进制格式,支持多种编程语言,并在新版本中引入了更简洁的语法和更强的类型检查。了解如何使用Protobuf 3进行消息定义、编码与解码,以及在实际项目中的应用。
摘要由CSDN通过智能技术生成
Google Protobuf 3版本介绍
本文编写时, Google 官方的 protobuf 版本是3.0.0beta

下面介绍下proto3的一些细节变化

Proto3的语法变化
语法标记
这个版本的protoc的protobuf编译器已经可以支持proto2语法和proto3的语法

如果你的proto文件没有添加syntax说明的话, 用这个版本的编译器会报错, 提示你默认proto2支持, 请添加语法标记

syntax = "proto2";

 

optional不需要了
只保留repeated标记数组类型, optional和required都被去掉了

实际使用证明, required的设计确实是蛋疼, C++的调试版会弹出assert,release版和optional也没啥区别

map支持
map编写格式为

map<key_type, value_type> map_field = N;
例如:
map<string, Project> projects = 3;
代码生成确认支持map, 这对于很多语言来说又可以偷懒了
字段default标记不能使用了
位于proto2语法的字段number后的[default=XX]

这个东西不能用了, 理由是:

对于同一段序列化后的数据, 如果序列化端的default和反序列化端的default描述不一样会导致最终结果完全不一致

即: 同一个数据两个结果, 这是不可预测的结果, 因此干掉这个特性

不过本人觉得, 对于游戏来说, 这个功能本身可以压缩很多数据,虽然会有隐患

 

枚举默认值一定是0
proto2里的默认值是枚举的第一个value对应的值, 不一定为0

proto3在你定义value时, 强制要求第一个值必须为0

这个修改为避免隐患还是有帮助的

泛型描述支持
any类型, 可以代表任何类型, 可以先读进来, 再进行解析, 没具体用, 步子跨大了怕扯到蛋

支持json序列化
这个极好, json再次被同化了

增加了多种语言支持
js, objc, ruby, C#等等

然而, C#版本的基础runtime库是用C# 6.0的语法写的,这对于Unity mono祖传2.0来说, 确实扯到蛋了,没法用

Protobuf现在使用CMAKE做配置系统
编译起来稍微麻烦, 还要下个被墙掉的cmake…

 

 

第三方库里对于proto3的变化
Golang的官方protobuf支持: https://github.com/golang/protobuf

生成代码中的结构体字段类型变化
对于proto2的文件, 生成的go代码中的结构体依然使用类型指针作为默认存储, 兼容老的系统

对于proto3的文件, 生成的go代码中的结构体直接使用字段作为默认存储, 不再使用GetXXX来作为字段值访问, 赋值时也无需使用proto.类型() 函数进行指针类型字段值创建.

这个调整很是方便, 但丢失了optional判断功能, 对应C++里就是hasXXX的功能, 不过好歹这个逻辑现在用的不多了

这个修改大概也是配合json序列化来做的, go默认的json序列化时, 无法使用proto2生成的结构体的, 因为都是指针,无法赋值..

 

新版protoc-gen-go的插件会生成descriptor的压缩数据
新插件会给每次生成的文件添加这样一段代码

var fileDescriptor0 = []byte{
    // 220 bytes of a gzipped FileDescriptorProto
    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x8f, 0xcd, 0x4e, 0xc5, 0x20,
    0x10, 0x85, 0x53, 0xbd, 0x35, 0x32, 0xb7, 0xdd, 0x4c, 0x5c, 0xb0, 0x70, 0x71, 0xd3, 0xb8, 0x70,
    0x75, 0x17, 0xfa, 0x04, 0xc6, 0xd8, 0xb8, 0x50, 0x63, 0xa8, 0x2f, 0x80, 0xed, 0x44, 0x89, 0x28,
    0x04, 0xc6, 0xbf, 0x47, 0xf1, 0x6d, 0x95, 0x49, 0x8d, 0x4d, 0x5c, 0x01, 0xdf, 0x39, 0x7c, 0x30,
    0x00, 0x1c, 0x82, 0xdf, 0xc6, 0x14, 0x38, 0xe0, 0xaa, 0xec, 0xbb, 0x37, 0x68, 0x2e, 0x3e, 0x62,
    0x48, 0x7c, 0x49, 0x76, 0xa2, 0x84, 0x47, 0xd0, 0xde, 0x96, 0xf8, 0xee, 0x33, 0xd2, 0x8d, 0x7d,
    0x26, 0x5d, 0x6d, 0xaa, 0x63, 0x65, 0xda, 0xb8, 0x84, 0xd8, 0x41, 0x63, 0xc2, 0x7b, 0xef, 0xc8,
    0x4f, 0x52, 0xda, 0x91, 0x52, 0x93, 0x16, 0x0c, 0x0f, 0x41, 0x89, 0xa9, 0x77, 0x9e, 0xf4, 0xae,
    0x14, 0x54, 0xfc, 0x05, 0xdd, 0x57, 0x05, 0x4a, 0xba, 0xd7, 0xc4, 0x16, 0xb7, 0x80, 0x03, 0x27,
    0xf7, 0xf2, 0x70, 0x72, 0xe5, 0x32, 0x0f, 0xd1, 0x3b, 0xa6, 0x34, 0x5b, 0x31, 0xff, 0x4b, 0x70,
    0x03, 0x6b, 0x43, 0x91, 0x2c, 0x9f, 0x3f, 0xd2, 0xf8, 0x24, 0xf6, 0x7d, 0xb3, 0x4e, 0x7f, 0x08,
    0x0f, 0xa0, 0x3e, 0xf3, 0xce, 0x66, 0xbd, 0x12, 0x49, 0x6d, 0xcb, 0xa1, 0x4c, 0x37, 0xbf, 0xf3,
    0xb3, 0xbc, 0x8e, 0xac, 0x6b, 0xb9, 0xd9, 0xe6, 0x25, 0xbc, 0xdf, 0x93, 0x6f, 0x9e, 0x7e, 0x07,
    0x00, 0x00, 0xff, 0xff, 0x0c, 0x9f, 0x10, 0xa8, 0x2e, 0x01, 0x00, 0x00,
}

对于meta信息的提取还是很方便的

然而

对于多个文件的生成, 这样做非常的麻烦, 因为这个字段会重复导致编译错误

很多人在论坛里吐槽, 官方给出的解决方法是, 使用protoc一次性传入一个package下的所有的proto直接生成一个go

而不是现在的一个proto一个go

生成代码会自动注册到全局, 并可以方便的查询
以前这个代码需要自己来做, 现在官方提供了支持, 很是方便

然而, 为什么不支持遍历… 残念啊, 又要自己动手了

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值