22

Protobuf - 更小、更快、更简单的交互式数据语言

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzA4Mjc1NTMyOQ%3D%3D&%3Bmid=2247484148&%3Bidx=1&%3Bsn=1395f7521f2a46909441f72a00e46b66
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JvMZNbr.jpg!mobile

01

概念

Protocol buffers  是 Google 的一种语言中立、平台中立,可扩展,用于序列化结构化数据的交互式数据语言。相比 JSON、XML,它更小、更快、更简单。

02

基本语法

定义一个消息类型:

新建一个 user.proto 文件:

syntax = "proto3";



package message;



message UserRequest {

int64 uid = 1;

string username = 2;

}

  • .protoc 文件中非空、非注释的第一行,使用关键字 syntax 指定使用的是 proto3 语法,如果未使用关键字 syntax 指定,则默认使用 proto2 语法。

  • package 关键字,用来声明消息类型的可见范围。

  • UserRequest 消息类型共有 2 个字段,每个字段包含3 个属性:数据类型、字段名称和字段编号,其中字段名称和字段编号不可重复。

字段编号从 1 到 2^29 - 1(536,870,911),不可使用预留字段编号 19000-19999,其中 1-15 占用 1 字节,应该用于频繁出现的字段。

在一个.proto文件中,可以定义多个消息类型。

03

标量数据类型

Protobuf 生成的数据类型与原始类型并不完全一致, 该表格展示了定义于 .proto 文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:

.proto Type Go Type float64 float32 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint32替代。 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代。 使用变长编码。 使用变长编码。 使用变长编码,这些编码在负值时比int32高效的多。 使用变长编码,这些编码在负值时比int64高效的多。 fixed32 总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。

续:

fixed64 总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。 sfixed32 总是4个字节。 sfixed64 总是8个字节。 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。 可能包含任意顺序的字节数据。

04

更多用法

  • 默认值

  • enum

  • 嵌套

  • Any

  • oneof

  • map

限于篇幅,如需了解上述内容,请阅读文档。

官方文档:

https://developers.google.com/protocol-buffers/docs/proto3

中文翻译:

https://colobu.com/2017/03/16/Protobuf3-language-guide

05

安装 protoc 编译器

protoc 是 Protobuf 的编译器,结合插件将我们编写的 .proto 文件编译成我们需要的编程语言代码。

  1. 下载安装文件

    wget https://github.com/protocolbuffers/protobuf/releases/download/v3.13.0/protobuf-all-3.13.0.zip

  2. 解压缩

    unzip protobuf-all-3.13.0.zip

  3. 检查

    cd protobuf-all-3.13.0

    ./configure

  4. 编译

    make

  5. 安装

    make install

注意:安装过程中,可能会提示需要依赖库,可以根据错误提示安装依赖库。另外,如果你使用的是 macOS,系统已经预装了 protoc,无需重复安装。

06

安装 protoc 插件

protoc-gen-go( Go 代码生成插件

  1. 使用 go get 命令安装

    go get -u github.com/golang/protobuf/[email protected]

  2. 确保生成的 proto c-gen -go 可执行文件在相应的 bin 目录中。

  3. 编译 .proto 文件。

    protoc --go_out=. *.proto

  • --go_out:编译文件的存放目录

  • *.protoc 目标编译文件,*星号代表文件名的通配符

07

使用 proto 包的函数操作 protobuf

proto 包提供了操作 protobuf 的一系列函数,其中序列化和反序列化函数比较常用,用来将数据序列化后进行传递。

序列化:

func proto.Marshal(m protoiface.MessageV1) ([]byte, error)

Marshal returns the wire-format encoding of m.

反序列化:

func proto.Unmarshal(b []byte, m protoreflect.ProtoMessage) error

Unmarshal parses the wire-format message in b and places the result in m.

更多关于 proto 包的函数使用方法,请查阅文档:

https://pkg.go.dev/google.golang.org/protobuf/proto

08

总结

本文简单描述了 protobuf 的基本语法,如何安装 protoc 和 protoc 插件 protoc-gen-go ,如何将 .proto 文件编译成 go 文件。通过阅读本文,读者应该可以完成编写.proto文件,并使用 protoc 编译器和插件生成 go 文件。

B3yUfqm.jpg!mobile

推荐阅读:

Go 使用标准库 net/rpc 包


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK