Protocol Buffer使用枚举类型

4

你好,我正在使用 protobuf 进行开发,但是遇到了一个问题。

我有一些枚举函数,但其中两个有相同的别名。当我尝试将文件编译为某些语言(如 go)时,编译器会返回错误信息。

我已经按照 protobuf 文档中的示例定义了该枚举,但仍然无法解决问题。

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.
}

这是谷歌文档中说,如果您需要在一些不同的枚举中使用相同的别名,则需要在枚举中添加选项“option allow_alias = true;”。但是,在尝试编译.proto文件后,编译器会响应以下错误信息:

example.proto:13:5: "UNKNOWN" 在 "namespace" 中已经定义。
example.proto:13:5: 枚举值使用 C++ 作用域规则,这意味着枚举值是其类型的兄弟,而不是其子级。
因此,“UNKNOWN”必须在“kluso”内唯一,而不仅仅是在“EnumNotAllowingAlias”内唯一。

example.proto:14:5: "STARTED" 在 "namespace" 中已经定义。
example.proto:14:5: 枚举值使用 C++ 作用域规则,这意味着枚举值是其类型的兄弟,而不是其子级。
因此,“STARTED”必须在“kluso”内唯一,而不仅仅是在“EnumNotAllowingAlias”内唯一。

我不知道出了什么问题。有人知道问题出在哪里吗?
4个回答

4

allow_alias允许您为相同的值拥有两个不同的名称

但是,它仍然不允许您使用相同的名称两次!

在您从文档中获取的示例中,他们只是想演示如何通过将allow_alias设置为true在同一枚举类型中使用STARTED = 1和RUNNING = 1。他们提供的两个枚举示例不适用于同一包。

但是,如果您已经在EnumAllowingAlias中拥有RUNNING,则无法在EnumNotAllowingAlias中再次使用RUNNING,如果它们位于同一个软件包中。


1
我想在这里评论一下Go的用户体验有多糟糕。需要解决这个限制?没问题,只需像这样添加前缀 ENUMALLOWINGALIAS_UNKNOWN 对吧?顺便说一句,Go编译器会尝试通过为枚举值添加前缀来“帮助”你;这通常很好。但是现在,在这种情况下,您的常量被定义为 <package_name>.EnumAllowingAlias_ENUMALLOWINGALIAS_UNKNOWN(插入 facepalm 表情)。 - jackic23

3
你要找的答案就在错误信息里 :) 只是有点难以解析它实际想告诉你什么。
基本上,
枚举值是其类型的兄弟,而不是子元素
的意思是,枚举值不是作为MyEnum.FOOMyEnum2.FOO的作用域,它们被作用域在与 MyEnum 相同的级别。因此,在同一个 .proto 文件中,两个枚举值不能具有相同的名称;它们都试图作为FOO存在于该文件中,而不是作为MyEnum.FOOMyEnum2.FOO

哦,我错过了你设置了allow_aliasing。嗯。 - BlueSpaceCanary

1

EnumAllowingAlias 和 EnumNotAllowingAlias 不能在同一个 proto 文件中定义,它们只是两个用来理解 allow_alias 用法的例子。

allow_alias 只能在同一个 enum 中使用,正如 mahdt 所说,allow_alias 允许你在一个 enum 中为同一个值拥有两个不同的名称,EnumAllowingAlias 就是这种情况的例子:

enum EnumAllowingAlias {
  option allow_alias = true;
  UNKNOWN = 0;
  STARTED = 1;
  RUNNING = 1;
}

如果allow_alias未设置为true,则EnumNotAllowingAlias将会出现错误:

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

在Java中,枚举类型的使用没有这个限制。我认为这对大多数开发人员来说真的很令人困惑,因此我提出了一个错误报告:https://github.com/protocolbuffers/protobuf/issues/5425


0

我不明白你的观点,因为我有两个枚举,它们的名称不同。第一个是EnumAllowingAlias,第二个是EnumNotAllowingAlias。这是一个例子:

https://developers.google.com/protocol-buffers/docs/proto#enum

在示例之前,他们解释说:

“您可以通过将相同的值分配给不同的枚举常量来定义别名。要做到这一点,您需要将allow_alias选项设置为true,否则协议编译器将在发现别名时生成错误消息。”

在这种情况下,我可以创建两个枚举,如下所示,编译器应该首先使用别名创建第一个枚举,然后再创建第二个没有别名的枚举,但是编译器却在第一个答案中向我发送了错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接