草庐IT

java - 解决由于 C++ 导致的 Google protobuf 中枚举字段命名限制的解决方案

coder 2023-09-02 原文

您可能知道,当您在 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".

所以,这意味着你应该做类似的事情

  1. 用消息包装冲突的枚举。
    • 优点:嗯...协议(protocol)不会失败?
    • 缺点:生成代码将有一个额外的静态包装器类,因此它会稍微增加 SerDes 成本 + 命名似乎足够长。例如,CURRENCY.NAMESPACE(wrapper message name).USD

  1. 为字段使用前缀,因此如果您的冲突字段名称是 UNKNOWN 并且它是 CURRENCY,它将是 CURRENCY.CURRENCY_UNKNOWN 或类似的名称。
    • 优点:简单
    • 缺点:与 #1 一样丑陋,与没有任何前缀的现有枚举字段命名不一致。

  1. 只是不要使用枚举。使用字符串类型。
    • 优点:简单,不需要定义后备枚举字段,例如 UNKNOWN = 1 作为默认值。
    • 缺点:失去枚举的好处。

似乎 C++ 11 支持更好的枚举,没有这个问题,但不幸的是最新的协议(protocol)不支持它,我们不能简单地要求其他消费者在不使用 C++ 的情况下换用 C++ .

因此,它将选择不太差的解决方案而不是最佳解决方案,此时我们可能会使用 #2。有没有人有同样的经历并告诉我你的解决方案是什么,结果如何?

最佳答案

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

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

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

关于java - 解决由于 C++ 导致的 Google protobuf 中枚举字段命名限制的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27030332/

有关java - 解决由于 C++ 导致的 Google protobuf 中枚举字段命名限制的解决方案的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  8. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  9. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐