Protocol Buffers 3:枚举作为映射中的键

Protocol Buffers 3: Enums as keys in a map

不允许将枚举用作映射中的键。这里的 PaxType 是一个枚举,不允许用作键。

enum PaxType {
    ADULT = 0 ;
    CHILD = 1 ;
    INFANT = 2 ;
}

message FlightData {
    map<PaxType, FareType> fareType = 1;
}

这是不允许的,因为它不能很好地处理 proto3 开放枚举语义。例如,在Java中,如果你有一个Map,那么key只能是定义值之一。如果您碰巧从不在定义值集中的远程 client/server 接收到枚举键值,则无法将其放入 Map 中。这个限制迫使我们要么删除具有未知枚举键的映射条目(这违反了 proto3 开放枚举语义),要么禁止枚举作为映射键。

供参考:https://groups.google.com/forum/#!topic/protobuf/ikeldBe60eI

正如 Vivek Sinha 所说,不允许使用枚举作为映射中的键。但是,您可以使用列表并按照您定义枚举的相同顺序填充它。例如,当您编写一个使用生物群落的游戏时,您希望在世界中有一个从 biom typenumber of existing bioms 的映射。这可以通过以下方式完成:

enum BiomType {
    PLACEHOLDER = 0;
    FOREST = 1;
    DESERT = 2;
}

message Map {
    repeated int32 biom_distribution = 1;
}

当您填充 biom_distribution 列表时,您必须保持枚举中元素的顺序(在本例中为 BiomType)。

定义您自己的地图条目类型,例如:

enum MyEnum {
  FOO = 0;
  BAR = 1;
  BAZ = 2;
}

message MapEntry {
  MyEnum type = 1;
  int32 count = 2;
}

message MyMessage {
  repeated MapEntry counts = 1;
}

您不会获得 map 的确切语义或行为,例如具有相同键的重复条目被减少为最后收到的值,但您将获得相同的兼容性优势和相同的通用工具。