Protocol Buffers 是谷歌开发的语言无关的数据交换格式,也是序列化结构数据的扩充机制,与 XML 类似,但是更小更简单。
构建新 API 的动机
Go 的首个 Protocol Buffers 软件包已经发布了十年,在这十年里,此软件包与 Go 一起发展壮大,它的用户需求也有所增长。Go 官方提到,不少开发者希望编写使用反射(Reflection)来检查协议缓冲区(protocol buffer)消息的程序,但reflect
反射软件包只可检测 Go 的类型和数值,会忽略来自协定缓冲区类型系统中的信息。例如,我们可能想编写一个遍历日志条目并清除任何注释为包含敏感数据的字段的函数,但由于注释字段不是 Go 类型系统的一部分,所以操作起来比较麻烦。
除此之外,开发者会使用协议缓冲区编译器生成的数据结构之外的其他数据结构,例如能够代表其消息类型在编译时未知的动态消息类型。最后,proto.Message
也是常见的问题根源。
官方表示,上述三个问题都有一个共同的原因,也有一个共同的解决方案:Message
接口应完全指定消息的行为,并且对Message
值进行操作的函数应自由接受可以正确实现接口的任何类型。
由于Message
在保持包 API 兼容的同时无法更改类型的现有定义,因此官方决定推出全新的 Protocol Buffers 模块,且新版本与旧版本不兼容。
Reflection(反射)就是新版本的旗舰功能,它提供了类似reflect
反射软件包检测
Go 的类型和数值的功能。Protocol Buffers 的反射功能会根据 Protocol Buffers
的类型,提供检测系统数值的能力,该软件包包含了类型描述符,描述了来源文件和数值接口中定义的类型结构,其提供了检查和操作消息的能力。
官方把 Go Protocol Buffers 原来的版本称为 APIv1,而新版本称为 APIv2,由于 APIv1 和 APIv2 不兼容,因此针对每个版本使用了不同的模块路径。官方提到,因为每个开发者迁移到新版本的速度不同,且部分程序可能会持续使用旧版本,甚至在同一个程序中,也有可能会使用不同的 API 版本,因此官方目前打算无限期地支持 APIv1。
github.com/golang/protobuf@v1.3.4
是最接近 APIv2 之前的 APIv1 版本github.com/golang/protobuf@v1.4.0
是根据 APIv2 实现的 APIv1 版本google.golang.org/protobuf@v1.20.0
是 APIv2 版本