由于 C++ 而解决 Google protobuf 中的枚举字段命名限制的解决方案
Posted
技术标签:
【中文标题】由于 C++ 而解决 Google protobuf 中的枚举字段命名限制的解决方案【英文标题】:solutions to resolve enum field naming restriction in Google protobuf due to C++ 【发布时间】:2015-01-17 18:25:01 【问题描述】:您可能知道,当您在 Google protobuf 中使用全局范围或在同一消息中定义枚举时,如果枚举是同级的,则无法将枚举字段名称定义为相同。
即使您要使用 proto 文件生成 Java 代码,protoc 也会抱怨它并且不会生成任何带有以下消息的代码。
"XXX" is already defined in "your.package.name".
Note that enum values use C++ scoping rules, meaning that enum values are siblings of their type,
not children of it.
Therefore, "XXX" must be unique within "your.package.name", not just within "your_enum_name".
所以,这意味着你应该做类似的事情
-
用消息包装冲突的枚举。
优点:嗯...协议不会失败?
缺点:生成代码将有一个额外的静态包装类,因此它会稍微增加 SerDes 成本 + 命名似乎足够长。例如,CURRENCY.NAMESPACE(包装消息名称).USD
或
-
为字段使用前缀,因此如果您的冲突字段名称是 UNKNOWN 并且它是 CURRENCY,它将是 CURRENCY.CURRENCY_UNKNOWN 或类似的名称。
优点:简单
缺点:和 #1 一样丑陋,与没有任何前缀的现有枚举字段命名不一致。
或
-
只是不要使用枚举。使用字符串类型。
优点:简单,不需要默认定义像 UNKNOWN = 1 这样的后备枚举字段。
缺点:失去枚举的好处。
似乎 C++ 11 支持没有这个问题的更好的枚举,但不幸的是最新的 protoc 不支持它,我们不能简单地要求其他消费者在他们不使用 C++ 的情况下转而使用它.
因此,将选择不太差的解决方案而不是最佳解决方案,此时我们可能会使用#2。有没有人有同样的经历,告诉我你的解决方案是什么,结果如何?
【问题讨论】:
解决方法:关注vendor recommended style guide。 不要认为这是解决方案。例如,样式指南中的 Foo,您不能在与 Foo 同级的枚举中定义另一个 FIRST_VALUE 或 SECOND_VALUE。这就是这里的问题。 他们应该升级到enum class
。
@wonhee:是的,好点子。
【参考方案1】:
现有代码中流行的解决方案是选项(2):给每个枚举名称一个与其类型对应的前缀。这也有助于减少与宏的冲突。它很冗长,但与建议的其他选项不同,它没有运行时开销,并且对阅读代码的人造成的混淆最少。
(FWIW,Cap'n Proto 已经通过使用 C++11 枚举类避免了这个问题。protobufs 不太可能这样做,因为它会破坏现有代码。)
(披露:我是 Cap'n Proto 以及大部分 Google 开源 Protobuf 代码的作者。)
【讨论】:
Cap'n Proto 看起来不错,只是我需要一个基于 protoc 的解决方案,因为它现在在公司中被广泛使用,至少有三种不同的语言。以上是关于由于 C++ 而解决 Google protobuf 中的枚举字段命名限制的解决方案的主要内容,如果未能解决你的问题,请参考以下文章