为了最大化跨语言兼容性,Thrift标识符的推荐命名规范是什么?

4

在Thrift中,是否有推荐的标识符命名规范?

例如,我们有一个由通常是C#程序员的人编写的Thrift IDL。从这个生成的源代码可以在C#和Python中工作。然而,尽管可以从同一份Thrift文件生成Java代码,但是当IDL的作者给标识符命名与它们的类型完全相同的名称时,会出现Java编译器错误。例如:

enum DataType {
    Text,
    Integer
}

struct Metadata {
    1: string ColumnName,
    2: DataType DataType
}

请注意,“DataType”标识符与其类型名称相同,包括大小写。使用--gen java Thrift编译器选项生成的Java代码存在编译错误,例如:

Cannot make a static reference to the non-static field DataType

我虽然不是C#程序员,但我知道在C#中以大写字母开头的标识符名称是非常普遍的做法。目前为止,我们将不得不更改IDL以使用小写字母作为标识符名称(例如DataType dataType),并重新生成所有客户端;但如果有一些关于Thrift标识符命名约定的建议,那么我们就不会在其他语言中遇到类似的问题了。
顺便说一句,我尝试过--gen java:nocamel,但这没有解决问题。

你的结构体是否缺少字段ID? - JensG
很好的发现@JensG - 我刚刚把它们添加到我的帖子中。它们在原始IDL中就存在(我只是为了这篇文章总结其中的部分,并意外地省略了字段ID)。 - snark
1个回答

2
除了标识符的通常规则和编译器所提示的之外,没有强制或官方推荐的命名惯例。虽然已经有一些已知冲突进行了某种解决方法,但冲突仍有很多可能性。您必须找出适合自己的方法。
最好的方法是在IDL文件中重命名冲突字段,或者添加一个下划线。关于RPC和序列化,字段名称并不重要,只有字段ID才重要。因此,重命名字段不会破坏序列化数据的兼容性,而只影响源代码,这是可修复的事情。
编辑:这里有一个漂亮的例子,涉及到一个仍未解决的命名问题。由于问题的本质,它只会在一种非常特定的语言——Go中表现出来。只要使用Thrift支持的其他任何语言,您就不会遇到该IDL的任何麻烦。然而,应该修复诸如此类的问题。

我不理解你的最后一句话。我不想编辑源代码,因为那是自动生成的。我认为在Apache Thrift网站上提供一些关于命名的指导会很好。例如,我们可以推出广泛的Thrift服务,并且有许多Python和C#客户端正在工作。然后一年后我们决定创建Java客户端。砰——除非编辑IDL,否则Java客户端将无法工作,但这样做也意味着所有Python/C#客户端都必须重新生成!或者你的意思是只要字段ID不改变,Python/C#客户端就不需要更改? - snark
(1) 不,当然不是 - 修改IDL。(2) 关于命名问题,请提交一个JIRA工单,提到具体的问题,包括一个测试用例。(3) 这就是我所说的,是的。只有字段ID被序列化,因此不会破坏兼容性。在Thrift中真正序列化名称的唯一地方是服务方法调用。 - JensG
不用担心,@JensG - 我最近一直忙于其他的事情。我没有忘记你。希望很快就能提一个支持单…… - snark
1
好的@JensG,我已经提出了https://issues.apache.org/jira/browse/THRIFT-2435来解决这个问题。请注意,当我改变IDL后,我必须更改我的Python客户端。感谢您的建议。我同意应该修复这样的问题,这样当您决定以后添加对另一种语言的支持时,就不必修改其他语言中现有的客户端。 - snark

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