枚举

当定义消息类型时,可能希望它只能为预先定义多个值中的一个。假设为SearchRequest添加一个corpus字段, 而corpus可以是UNIVERSAL, WEB, IMAGES, LOCAL, NEWS, PRODUCTS 或 VIDEO. 你可以简单的添加一个枚举到消息定义, 为每个可能的值定义常量。

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

Corpus 枚举的第一个常量设置为0,每个枚举定义必须包含一个映射到0的常量作为它的第一个元素。

还可以给相同值的不同枚举常量定义别名,这时就需要设置allow_alias选项为true。否则protocol编译器发现别名的时候会发生错误。

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

枚举常量的定义范围同32位整型。枚举值也使用了varint编码方式。负值效率较低,不推荐使用。可以像上面例子一样在一个消息中定义并使用枚举,还可以应用外部定义的枚举,枚举定义在.proto文件中并可以重用,枚举可以当做别的消息中的字段使用。

如果通过完全删除枚举项或注释来更新枚举类型,那么如果使用了该.proto的旧版本,这可能会导致严重问题,比如数据损坏、隐私漏洞等。确保不会发生这种情况的一种方法是指定保留已删除条目的数值。如如果将来有任何用户试图使用这些标识符,协议缓冲区编译器会报错。可以使用max关键字指定保留的数值范围达到可能的最大值。

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

results matching ""

    No results matching ""