枚举类型

定义消息类型时,可能希望其中一个字段只包含预定义值列表中的一个。例如,假设您想为每个SearchRequest添加一个corpus(语料库)字段,其中语料库的值可以是UNIVERSAL、WEB、IMAGES、LOCAL、NEWS、PRODUCTS或VIDEO。您只需在消息定义中添加一个枚举,每个可能的值都有一个常量,就可以做到这一点。

在下面的示例中,我们添加了一个名为Corpus的枚举,其中包含所有可能的值,以及一个类型为Corpus的字段:

message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
Corpus corpus = 4;
}

如您所见,Corpus枚举的第一个常量映射到零:每个枚举定义必须包含一个映射到零的常量作为其第一个元素。这是因为:

  • 必须有一个零值,以便我们可以使用0作为数字默认值
  • 兼容proto2语法,按照proto2语法,第一个枚举值是默认值(而不是0)

可以通过将相同的值赋给不同的枚举常量来定义别名。为此,您需要将allow_alias选项设置为true,否则协议编译器将在找到别名时将生成错误消息。

message MyMessage1 {
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;
}
}
message MyMessage2 {
enum EnumNotAllowingAlias {
UNKNOWN = 0;
STARTED = 1;
// RUNNING = 1; // Uncommenting this line will cause a compile error inside Google and a warning message outside.
}
}

枚举器常量必须在32位整数的范围内。由于enum使用可变编码,因此负值效率很低,所以不建议使用。您可以在定义的消息内部定义枚举,如上面的示例所示,也可以在外部定义枚举——这些枚举可以在.proto文件中的任何消息定义中重用。您还可以使用_MessageType_._EnumType_语法将一条消息中声明的枚举类型用作另一条消息中的字段类型。

当使用协议缓冲区编译器编译一个使用了枚举.proto文件时,对于JavaC++来说,会生成一个对应的枚举类型;对于Python,会生成一个特殊EnumDescriptor类,用于在运行时生成的类中创建一组具有整数值的符号常量。

警告:生成的代码可能会受到特定语言的枚举数限制(一种语言的枚举数低千)。请检查您计划使用的语言的限制。

在反序列化过程中,无法识别的枚举值将保留在消息中,尽管反序列化消息时如何表示这些值取决于语言。在支持具有指定枚举范围以外值的开枚举类型的语言中,例如C++GO,未知的枚举值被简单地存储为其基础整数表示形式。在具有封闭枚举类型的语言(如Java)中,枚举中的大小写用于表示无法识别的值,并且可以使用特殊的访问器访问基础整数。在这两种情况下,如果消息被序列化,则无法识别的值仍将与消息一起序列化。

有关如何在应用程序中使用消息枚举的详细信息,请参阅所选语言的生成代码指南

保留值

如果通过完全删除枚举条目或把它注释掉来更新枚举类型,则将来的用户可以在自己更新该类型时重用该数值。如果以后加载相同.proto的旧版本,这可能会导致严重的数据损坏、隐私漏洞等问题。确保不会发生这种情况的一种方法是指定保留已删除条目的数值(和/或名称,这也可能导致JSON序列化问题)。如果将来有任何用户试图使用这些标识符,协议缓冲区编译器就会报错。您可以使用max关键字指定您的保留数值范围提高到可能的最大值。

enum Foo {
reserved 2, 15, 9 to 11, 40 to max;
reserved "FOO", "BAR";
}

请注意,不能在同一个reserved语句中混合使用字段名和数值。

原文:https://www.cnblogs.com/itheo/p/14273139.html

作者:Theo·Chan

版权:本文版权归作者和博客园共有

转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接,否则必究法律责任

最新文章

  1. 使用GIT进行源码管理 —— 在VisualStudio中使用GIT
  2. RainCup_No.1
  3. SpringMVC接收页面表单参数
  4. Atitit 破解qq空间(2)-------探测权限
  5. LaTeX内容总结
  6. c++表达式的一些小小的注意事项
  7. 程序退出异常_DebugHeapDelete和std::numpunct
  8. python 调用内部类的两种方法
  9. Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
  10. Entity Framework Code First级联删除
  11. about compiler synergy
  12. poj 3252
  13. JavaWeb一小时急速入门总结反思
  14. HTML- 标签语法
  15. 2_PY基本数据类型
  16. VSIX 插件右键菜单(2)
  17. 安卓面试题 Android interview questions
  18. wincc项目移植和复制解决办法
  19. hdu 5693 && LightOj 1422 区间DP
  20. 【转】mybatis 自增主键配置

热门文章

  1. Java异常体系概述
  2. 短信平台软件开发,短信发送平台销售,短信软件源码,G客短信发送平台
  3. JAVA_基础反射创建运行时类的对象
  4. Goland 设置代码格式化
  5. N叉树的最大深度-DFS
  6. Docker安装MySQL,Redis,阿里云镜像加速
  7. 【Linux】fio测试读写速度
  8. 【Linux】快速创建文件的命令方法
  9. P1341 无序字母对(欧拉回路)
  10. 使用sqluldr2进行oracle数据库抽取时执行后无反应,也无日志