二.protobuf3数据类型
定义数据类型
首先让我们看一个非常简单的例子。假设您想要定义搜索请求消息格式,其中每个搜索请求都有一个查询字符串、您感兴趣的特定结果页面以及每页的结果数量。这是用来定义消息类型的.proto文件。
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
文件的第一行指定您正在使用proto 3语法:如果不这样做,协议缓冲区编译器将假设您正在使用proto 2。这必须是文件的第一个非空的非注释行。
SearchRequest消息定义指定了三个字段(名称/值对),每一个字段对应于要包含在这种类型的消息中的数据。每个字段都有一个名称和一个类型。
指定字段类型
在上例中,所有字段都是标量类型:两个整数(page_number和result_per_page)和一个字符串(query)。但是,您也可以为字段指定复合类型,包括枚举和其他消息类型。
分配字段编号
如您所见,消息定义中的每个字段都有一个唯一的编号。这些字段编号用于以二进制格式标识您的字段,一旦您的消息类型被使用,就不应该被更改。请注意,1到15范围内的字段编号需要一个字节来编码,包括字段编号和字段类型(您可以在协议缓冲区编码中找到更多信息)。16到2047范围内的字段编号需要两个字节。因此,您应该为经常出现的消息元素保留数字1到15。记住为将来可能添加的频繁出现的元素留出一些空间。
您可以指定的最小字段编号为1,最大字段编号为229 - 1,即536,870,911。但是不能使用数字19000到19999 ( FieldDescriptor::kFirstReservedNumber 到FieldDescriptor::kLastReservedNumber),因为它们是为协议缓冲区实现而保留的-如果您在 .proto文件中使用这些保留的数字之一,协议缓冲区编译器就会报错。同样,您也不能使用任何保留字段。
指定字段规则
消息字段可以是以下字段之一:
singular: 可以有零个或其中一个字段(但不超过一个)。
repeated: 该字段可以重复任意次数(包括零次)。重复值的顺序将被保留。
在proto 3中,可扩展的repeated字段为数字类型的默认编码。
您可以在协议缓冲区编码中找到更多关于打包编码的信息。
添加更多消息类型
可以在单个.proto中定义多种消息类型。如果您要定义多个相关消息,这很有用——例如,如果您想定义与搜索响应消息类型相对应的回复消息格式,可以将其添加到该.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.
}
保留字段
如果通过完全删除某个字段或对其进行注释来更新消息类型,将来的用户可以在对该类型进行自己的更新时重用该字段编号。如果他们以后加载旧版本的相同.proto文件,这可能会导致严重的问题 ,包括数据损坏、隐私漏洞等。确保不会发生这种情况的解决方案是指定已删除字段的字段编号(and/or名称,这也可能导致JSON序列化问题)是保留的。如果将来有任何用户试图使用这些字段标识符,协议缓冲区编译器会报错。
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
请注意,不能在同一保留语句中混合字段名和字段编号。
从.proto文件中生成了什么?
在.proto上运行协议缓冲区编译器时,编译器用您指定的编程语言生成代码,您需要使用您在文件中描述的消息类型,包括获取和设置字段值,将消息序列化为输出流,以及从输入流解析消息。
对于C++,编译器会从每个 .proto文件生成一个 .h and .cc文件, 文件中描述的每种消息类型都有一个类。
对于Java,编译器为每个消息类型生成一个Java文件,其中包括每个类的定义,以及用于创建消息类实例的特殊构建器类。
Python有点不同,Python编译器生成一个模块,其中包含中每种消息类型的静态描述符,然后与元类一起使用,在运行时创建必要的Python数据访问类。
对于Go, 编译器生成一个.pb.go文件,其中包含文件中每种消息类型的类型。
对于Ruby, 编译器生成一个.rb文件带有包含消息类型的Ruby模块。
对于Objective-C, 编译器为每个.proto文件中生成一个pbobjc.h和pbobjc.m文件,文件中描述的每种消息类型都有一个类。
对于C#, 编译器为每个.proto文件生成一个.cs文件,文件中描述的每种消息类型都有一个类。
通过所选语言的教程( proto 3版本即将推出),您可以了解关于为每种语言使用API的更多信息。有关更多的API细节,请参见相关的API参考( proto 3版本也即将推出)。
二.protobuf3数据类型的更多相关文章
- 我的MYSQL学习心得(二) 数据类型宽度
我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- PHP语法(二):数据类型、运算符和函数
相关链接: PHP语法(一):基础和变量 PHP语法(二):数据类型.运算符和函数 PHP语法(三):控制结构(For循环/If/Switch/While) 这次整理了PHP的数据类型.运算符和函数. ...
- Mysql学习笔记(二)数据类型 补充
原文:Mysql学习笔记(二)数据类型 补充 PS:简单的补充一下数据类型里的String类型以及列类型... 学习内容: 1.String类型 2.列类型存储需求 String类型: i.char与 ...
- python基础(二)-------数据类型
python开发基础篇(二)数据类型 python数据类型有: 1.数字 1.只能存放一个值 2.一经定义,不可更改 3.直接访问 主要的分类为:整型,长整型,(python2有长整型的概念Pytho ...
- Typescript 学习笔记二:数据类型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- excel的宏与VBA入门(二)——数据类型与变量
一.属性与方法 1.属性 上面单击对象,下面即显示对应的属性: 2.方法 双击左上的对象,即可看到相应的方法: 二.数据类型 到 Boolean True 或 False , 到 , ,,, 到 ,, ...
- Hive(二)【数据类型、类型转换】
目录 一.基本数据类型 案例实操 二.集合数据类型 案例实操 Map类型 三.类型转换 1.隐式类型转换 2.显示(强制)类型转换 一.基本数据类型 HIVE MySQL JAVA 长度 例子 TIN ...
- MySQL(二) 数据库数据类型详解
序言 今天去健身了,感觉把身体练好还是不错的,闲话不多说,把这个数据库所遇到的数据类型今天统统在这里讲清楚了,以后在看到什么数据类型,咱度应该认识,对我来说,最不熟悉的应该就是时间类型这块了.但是通过 ...
- c#学习<二>:数据类型
基元类型 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到Framework类库(FCL)中存在的类型(BCL是FCL的子集). C#中的基元类型 BCL类型 ...
随机推荐
- Java-Readable
import java.nio.*; import java.util.*; import static net.mindview.util.Print.*; public class RandomW ...
- 本地yum源 、阿里yum源、163yum源的配置安装
一.本地yum源 (我使用的7.3版本) 1..添加一个新的yum源配置文件dvd.repo(文件名字自定义) vi etc/yum.repos.d 添加新的内容: name=rhel_dvd ...
- Python-09-文件处理
一.文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 #1. 打开文件,得到文件句柄并赋值给一个变量 f=open('a.txt','r',encoding='u ...
- python基础 — time库
时间获取-------time() ctime() gmtime() 时间格式化-------strftime() strptime() 程序计时-------sleep() perf_count ...
- springboot 配置elasticsearch Java High Rest Client
前提声明 在新版本的spring boot中逐渐放弃了对Spring Data Elasticsearch的支持,所以不推荐使用,使用ES官方推出的Java High Rest Client. 引入依 ...
- JVM运行参数优化详细教程
获取设置的参数str的值: 常用的-X参数有以下这些: 手动调用GC执行垃圾回收操作:(-XX:+DisableExplicitGC 手动调用将会失效) 查看tomcat的进程ID: 或者:
- go 学习笔记(4) --变量与常量
“_” 可以理解成一个垃圾桶,我们把值赋给“_” ,相当于把值丢进垃圾桶,在接下来的程序中运行中不需要这个下划线这个值 a,b :=1,2 只能用在函数体内 package main impor ...
- 系统开启UAC情形下开机自启动程序如何以管理员权限启动
系统开启UAC情形下开机自启动程序如何以管理员权限启动 题记:本文阐述的是在Windows系统开启UAC的情况下,开机自启动程序需要以管理员权限启动, 系统弹出UAC对话框,用户同意的情形下启动程序 ...
- .NET母版实例2(UI页面)
8.<div id="navlist"> <asp:SiteMapDataSource ID="SiteMapDataSource1" ...
- 记redis一次Could not get a resource from the pool 异常的解决过程
最近有个项目中的redis每天都会报 "Could not get a resource from the pool"的错误,而这套代码在另一地方部署又没有问题.一直找不到错误原因 ...