protobuf message定义_Protobuf语言指南

Protobuf是Google的序列化协议,用于结构化数据的高效存储和传输。本文档详细介绍了如何定义消息类型,包括指定字段类型、编号、规则,以及如何处理嵌套消息、枚举类型、默认值等。同时,还涵盖了导入其他消息定义、保留字段、生成不同编程语言的代码等内容,帮助开发者理解和使用Protobuf。
摘要由CSDN通过智能技术生成

什么是 Protobuf

Protobuf是Protocol Buffers的简称,它是Google公司开发的一种数据描述语言,用于描述一种轻便高效的结构化数据存储格式,并于2008年对外开源。Protobuf可以用于结构化数据串行化,或者说序列化。它的设计非常适用于在网络通讯中的数据载体,很适合做数据存储或 RPC 数据交换格式,它序列化出来的数据量少再加上以 K-V 的方式来存储数据,对消息的版本兼容性非常强,可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。开发者可以通过Protobuf附带的工具生成代码并实现将结构化数据序列化的功能。

Protobuf中最基本的数据单元是message,是类似Go语言中结构体的存在。在message中可以嵌套message或其它的基础数据类型的成员。

教程中将描述如何用protocol buffer语言构造你的protocol buffer数据,包括.proto文件的语法以及如何通过.proto文件生成数据访问类。教程中使用的是proto3版本的protocol buffer语言。

定义Message

首先看一个简单的例子,比如说你定义一个搜索请求的message,每一个搜索请求会包含一个搜索的字符串,返回第几页的结果,以及结果集的大小。在.proto文件中定义如下:

syntax = "proto3";

message SearchRequest {
    
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}
  • .proto文件的第一行指定了使用proto3语法。如果省略protocol buffer编译器默认使用proto2语法。他必须是文件中非空非注释行的第一行。
  • SearchRequest定义中指定了三个字段(name/value键值对),每个字段都会有名称和类型。

指定字段类型

上面的例子中,所有的字段都是标量类型的两个整型(page_number和result_per_page)和一个字符串型(query)。不过你还可以给字段指定复合类型,包括枚举类型和其他message类型

指定字段编号

在message定义中每个字段都有一个唯一的编号,这些编号被用来在二进制消息体中识别你定义的这些字段,一旦你的message类型被用到后就不应该在修改这些编号了。注意在将message编码成二进制消息体时字段编号1-15将会占用1个字节,16-2047将占用两个字节。所以在一些频繁使用用的message中,你应该总是先使用前面1-15字段编号。

你可以指定的最小编号是1,最大是2E29 - 1(536,870,911)。其中19000到19999是给protocol buffers实现保留的字段标号,定义message时不能使用。同样的你也不能重复使用任何当前message定义里已经使用过和预留的字段编号。

定义字段的规则

message的字段必须符合以下规则:

  • singular:一个遵循singular规则的字段,在一个结构良好的message消息体(编码后的message)可以有0或1个该字段(但是不可以有多个)。这是proto3语法的默认字段规则。(这个理解起来有些晦涩,举例来说上面例子中三个字段都是singular类型的字段,在编码后的消息体中可以有0或者1个query字段,但不会有多个。)
  • repeated:遵循repeated规则的字段在消息体重可以有任意多个该字段值,这些值的顺序在消息体重可以保持(就是数组类型的字段)

添加更多消息类型

在单个.proto文件中可以定义多个message,这在定义多个相关message时非常有用。比如说,我们定义SearchRequest对应的响应message SearchResponse ,把它加到之前的.proto文件中。

message SearchRequest {
    
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
    
 ...
}

添加注释

.proto文件中的注释和C,C++的注释风格相同,使用// 和 / ... /

/* SearchRequest represents a search query, with pagination options to
 * indicate which results to include in the response. */

message SearchRequest {
    
  string query = 1;
  int32 page_number = 2;  // Which page number do we want?
  int32 result_per_page = 3;  // Number of results to return per page.
}

保留字段

当你删掉或者注释掉message中的一个字段时,未来其他开发者在更新message定义时就可以重用之前的字段编号。如果他们意外载入了老版本的.proto文件将会导致严重的问题,比如数据损坏、隐私泄露等。一种避免问题发生的方式是指定保留的字段编号和字段名称。如果未来有人用了这些字段标识那么在编译是protocol buffer的编译器会报错。

message Foo {
    
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}

proto会生成什么代码

当使用protocol buffer编译器编译.proto文件时,编译器会根据你在.proto文件中定义的message类型生成指定编程语言的代码。生成的代码包括访问和设置字段值、格式化message类型到输出流,从输入流解析出message等。

  • For C++, the compiler generates a .h and .cc file from each .proto, with a class for each message type described in your file.
  • For Java, the compiler generates a .java file with a class for each message type, as well as a special
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值