为Go生成多个Thrift文件的正确方法

时间:2015-01-05 20:05:15

标签: go namespaces thrift

所以我有以下文件

/src/baseService.thrift
    /baseTypes.thrift
    /baseSecurity.thrift

我希望将所有这些thrift定义创建到一个库中。因此,每个文件的顶部是:

baseService.thrift
==================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar

import "baseTypes.thrift"

baseTypes.thrift
================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar

baseSecurity.thrift
===================
namespace java foo.bar
namespace cpp foo.bar
namespace js foo.bar
namespace go foo.bar

import "baseTypes.thrift"

问题是,如何将所有这些创建到一个lib包中?它适用于java / cpp / js,但是当我尝试构建它时,它就不行了。

有了节俭,你不能做thrift gen:baz *.thrift,你必须一次做一个文件。对于其他语言,我们只做一个:

for f in `find *.thrift`; do
   thrift -o myGenDir --gen go $f"
done

(用每个lang替换相应的gen命令)

对于Python来说这很好,因为它根据文件名[即foo / bar / {filename} /ttypes.py]将每个gen文件放入其自己的目录中。对于Java,它会转储foo / bar /中的所有文件,但每个类名都是唯一的。对于cpp,它将所有内容转储到gen目录中,但每个thrift文件[so {filename.h},{filename.cpp}]唯一命名。但是对于Go,它会将所有内容转储到foo / bar中,如下所示:

/foo/bar/constants.go
/foo/bar/service.go
/foo/bar/service-remote/
/foo/bar/baz/  [for anything that has a namespace of foo.bar.baz]
/foo/bar/ttypes.go

问题是,ttypes.go和(推测)constants.go被for循环中的最后一行覆盖。有没有解决的办法?它适用于其他语言 - 似乎是对Go的疏忽。我错过了什么我们有很多Thrift文件,里面有很多内容 - 我不必将同一个软件包级别的所有内容组合成一个旧文件。

2 个答案:

答案 0 :(得分:6)

  

问题是,ttypes.go和(大概)constants.go会被for循环中的最后一行所覆盖。

是的,那是真的。

  

有解决方法吗?

最(跨语言)的便携式建议是不要这样做。代替:

  • 将不同的IDL文件放入不同的名称空间
  • 将属于一个名称空间的所有内容放入一个IDL文件

Thrift编译器为Go提供了一些编译器开关,它们可以至少部分帮助您(通过在命令提示符下键入thrift --help获得所有语言的所有可用选项)

 go (Go):
   package_prefix=  Package prefix for generated files.
   thrift_import=   Override thrift package import path (default:git.apache.org/thrift.git/lib/go/thrift)
   package=         Package name (default: inferred from thrift file name)

这些选项的使用方式与

类似
 thrift -gen go:package=mypack,package_prefix=myprefix
  

它适用于其他语言 - 似乎是对Go的疏忽。

如果您对跨语言兼容性感兴趣,可能是您的印象,但我建议您不要尝试。行为与其他语言相同。举个例子:我最近修复了(或者更好:解决了)一个问题with the Erlang tests,在那里我不得不完全打击这个问题。

答案 1 :(得分:0)

最近有同样的问题。不同命名空间中的每个IDL都不起作用。代码看起来很糟糕,你必须记住各个不同的命名空间,为每一件小东西添加/删除命名空间都很烦人。

我只定义了一个命名空间,所以我来了。基本上,对象位于不同的文件中,但它们会在单个文件中写入。因此,没有导入,没有跨文件引用,每个文件中都没有名称空间。我将命名空间放在一个单独的文件中。然后我的脚本将所有内容连接成一个大的thirft文件并编译它。它确实要求你按正确的顺序放置所有内容,但它适用于我需要的语言 - Go,C#和Java工作正常。

对我而言,它看起来也像是一种疏忽。没有理由让它像Go一样。也许有一天我会发送一个合并请求,其行为更能与其他语言相匹配。