当前位置: 首页 > 知识库问答 >
问题:

解决谷歌protobuf中由于C引起的枚举字段命名限制的解决方案

施彬彬
2023-03-14

您可能知道,当您在 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的成本 命名似乎足够长。 例如,货币。命名空间(包装器消息名称)。美元

    • 优点 : 简单
    • 缺点 :与#1一样丑陋,与没有任何前缀的现有枚举字段命名不一致。

    • 优点:简单,不需要定义像 UNKNOWN = 1 这样的回退枚举字段作为默认值。
    • 缺点 :失去拥有枚举的好处。

    似乎 C 11 支持没有此问题的更好枚举,但不幸的是最新的 protoc 不支持它,我们不能简单地要求其他消费者在不使用 C 的情况下切换他们的一方使用 C。

    因此,它将选择不太差的解决方案而不是最佳解决方案,并且可能我们将在这一点上使用#2。有没有人有同样的经验,告诉我你的解决方案是什么,它是如何结束的?

共有1个答案

苏畅
2023-03-14

现有代码中的流行解决方案是选项 (2):为每个枚举名称指定一个与其类型相对应的前缀。这也有助于减少与宏的冲突。它很冗长,但与建议的其他选项不同,它没有运行时开销,并且对阅读代码的人造成的混乱最少。

(FWIW,Cap'n Proto通过使用C 11枚举类解决了这个问题。protobufs 不太可能这样做,因为它会破坏现有的代码。

(披露:我是Cap'n Proto以及Google大多数开源Protobuf代码的作者。

 类似资料:
  • 问题内容: 是否有比这更好的“解决方法”?访问TableMap上的方法时,我想避免使用PREFIX(局部变量)。 解决方法! 需要! 整个代码示例: 问题答案: 我认为您可能正在尝试将过多的情报投入其中。 我发现这种方法非常有用。它避免了由于无法扩展s 而引起的许多问题(实际上,您可以但不能以非常有用的方式)。 本质上,将其作为子类并将其特性作为传递给您的超类。这样,您仍然可以获得包括类型安全性在

  • mariadb 10.2中似乎有一个突破性的变化。7如果尝试重命名字段可为Null的datetime列,并且如果运行迁移,将出现错误: 创建迁移: 创建第二次迁移以重命名列: 有没有一个解决办法来让这个工作? 根据条令/dbal问题: 为了允许表达式作为默认值,并将其与文字区分开来,Mariadb现在在信息模式中引用默认值。列表。这一变化在(Oracle-)Mysql/MariaDB平台之间带来了

  • 请任何一个建议我对我的Android应用程序的逻辑怀疑。 我的应用程序不需要注册即可使用。但是我需要向所有用户发送推送通知(比如GCM)。所以我制作了一个数据库表,如下所示 因此,逻辑如下 现在的问题是 情况1:当用户在手机中“清除数据”并重新启动应用程序时,将发生另一个注册过程。因此,当我们发送消息推送时,用户将获得多次(自上次gcmrecd出现在我们的数据库中) 因为它是一个简单的新闻应用程序

  • 本文向大家介绍Django 解决由save方法引发的错误,包括了Django 解决由save方法引发的错误的使用技巧和注意事项,需要的朋友参考一下 最近项目中的资产的任务状态频频出现问题,查看日志文件,看代码逻辑,也没发现什么具体的错误,总是过段时间就会出现一个表的字段没有更新的问题,很头疼。 开始时,觉得是没有添加事务,所以同时更新两个不同的表,其中一个表的内容没有写进去;加了事务后,又出现这种

  • 我正在开发一个使用 AWS SNS 和 APNS 和 GCM 的推送通知架构。我所遵循的模型是 每个用户(而不是设备)都有一个与之对应的SNS主题。 每个用户可以有多个设备。 为每个设备创建平台应用程序endpoint。 将平台应用程序endpoint订阅到属于设备用户的主题 这样,当我们必须向用户的所有设备发送通知时,我们需要使用用户的调用,其所有设备都应该得到消息。 但是,默认情况下,AWS

  • 本文向大家介绍Mybatis动态调用表名和字段名的解决方法,包括了Mybatis动态调用表名和字段名的解决方法的使用技巧和注意事项,需要的朋友参考一下  一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能。今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查询以及某些字段是否显示,如某张表的某些字段不让用户查询到。这种情况下,就需要构建sql来动态传入表名、字段

  • 本文向大家介绍谷歌地图打不开的解决办法,包括了谷歌地图打不开的解决办法的使用技巧和注意事项,需要的朋友参考一下 谷歌地图被中国防火墙封杀,所以不用直接引用http://maps.googleapis.com/maps/api/js?sensor=false&language=en这域名下的谷歌地图api,而是改为http://maps.google.cn/maps/api/js?sensor=fa