定义数据类型

首先让我们看一个非常简单的例子。假设您想要定义搜索请求消息格式,其中每个搜索请求都有一个查询字符串、您感兴趣的特定结果页面以及每页的结果数量。这是用来定义消息类型的.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数据类型的更多相关文章

  1. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  2. PHP语法(二):数据类型、运算符和函数

    相关链接: PHP语法(一):基础和变量 PHP语法(二):数据类型.运算符和函数 PHP语法(三):控制结构(For循环/If/Switch/While) 这次整理了PHP的数据类型.运算符和函数. ...

  3. Mysql学习笔记(二)数据类型 补充

    原文:Mysql学习笔记(二)数据类型 补充 PS:简单的补充一下数据类型里的String类型以及列类型... 学习内容: 1.String类型 2.列类型存储需求 String类型: i.char与 ...

  4. python基础(二)-------数据类型

    python开发基础篇(二)数据类型 python数据类型有: 1.数字 1.只能存放一个值 2.一经定义,不可更改 3.直接访问 主要的分类为:整型,长整型,(python2有长整型的概念Pytho ...

  5. Typescript 学习笔记二:数据类型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. excel的宏与VBA入门(二)——数据类型与变量

    一.属性与方法 1.属性 上面单击对象,下面即显示对应的属性: 2.方法 双击左上的对象,即可看到相应的方法: 二.数据类型 到 Boolean True 或 False , 到 , ,,, 到 ,, ...

  7. Hive(二)【数据类型、类型转换】

    目录 一.基本数据类型 案例实操 二.集合数据类型 案例实操 Map类型 三.类型转换 1.隐式类型转换 2.显示(强制)类型转换 一.基本数据类型 HIVE MySQL JAVA 长度 例子 TIN ...

  8. MySQL(二) 数据库数据类型详解

    序言 今天去健身了,感觉把身体练好还是不错的,闲话不多说,把这个数据库所遇到的数据类型今天统统在这里讲清楚了,以后在看到什么数据类型,咱度应该认识,对我来说,最不熟悉的应该就是时间类型这块了.但是通过 ...

  9. c#学习<二>:数据类型

    基元类型 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到Framework类库(FCL)中存在的类型(BCL是FCL的子集). C#中的基元类型 BCL类型 ...

随机推荐

  1. springboot获取上下文ApplicationContext

    在springboot主程序里改成 public static void main(String[] args) { // SpringApplication.run(SpringbootAPP.cl ...

  2. Spring中的常用注解

    Spring中的常用注解 1.@Controller 标识一个该类是Spring MVC controller处理器,用来创建处理http请求的对象.

  3. [转帖]IOC Security: Indicators of Attack vs. Indicators of Compromise

    IOC Security: Indicators of Attack vs. Indicators of Compromise https://www.crowdstrike.com/blog/ind ...

  4. 【转帖】国产PCIe SSD主控芯片获得中国芯大奖 3500MB/s读取

    国产PCIe SSD主控芯片获得中国芯大奖 3500MB/s读取 https://www.cnbeta.com/articles/tech/906033.htm 国产主控 在日前的2019“中国芯”集 ...

  5. linux命令kill和kill -9的区别

    linux命令kill和kill -9的区别 2018年04月13日 16:53:07 坠入苦海销尘垢 阅读数 2854   转载自https://www.cnblogs.com/liuhouhou/ ...

  6. adb常用命令总结

    针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命令将会用于自动化测试的脚本当中. And ...

  7. Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法

    最近看到了 java.util.PriorityQueue.刚看到还没什么感觉,今天突然发现他可以用来找N个数中最小的K个数. 假设有如下 10 个整数. 5 2 0 1 4 8 6 9 7 3 怎么 ...

  8. js光标定位操作

    1. 自动选中区域内容 <html> <meta http-equiv="Content-Type" content="text/html; chars ...

  9. 创建包含CRUD操作的Web API接口2:实现Get方法

    本节是前一节的延续,上一节中我们已经为我们的Web API项目创建必要的基础设施. 在本节中,我们将在我们的控制器类中实现操作方法,这些方法用来处理HTTP GET请求. 根据Web API命名约定, ...

  10. 在 WPF 中获取一个依赖对象的所有依赖项属性

    原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...