在Thrift中,在对服务的方法调用的上下文中,列表可以直接用作参数或返回类型。如果您需要显式的对象(反)序列化,是否有一种方便的方法(在Java中)使用Thrift来(de)序列化List< TBase>而不必将其作为节俭IDL中的单独结构包装?
更具体地说,假设我已经在节俭中定义了
struct A {
1: required long x;
2: required long y;
}
我可以通过定义
来(de)序列化这些列表struct ListOfA {
1: required list<A> theList;
}
然后
ListOfA myList = ...
TSerializer serializer = new TSerializer();
byte[] mySerializedList = serializer.serialize(myList);
我的问题是,是否可以避免这种(略微不优雅的)额外结构的定义仅包含列表。
以下不起作用,因为TSerializer.serialize需要TBase
List<A> myList = ... // List<A> instead of ListOfA
TSerializer serializer = new TSerializer();
byte[] mySerializedList = serializer.serialize(myList); //does not compile
在IDL中使用typedef已经有所帮助,但它们似乎没有被翻译成Java类
typedef list<A> ListOfA
=&GT; ListOfA未在生成的Java代码中定义。
答案 0 :(得分:1)
我的问题是,是否可以避免这种(稍微不优雅的)额外结构的定义只包含列表
我建议相反:使用包装结构执行“低效”步骤。
Thrift允许任意数量的输入参数。但是,只能有一个返回值。没有var
或out
参数或多个返回值之类的东西,因此您实际上限制为最多一个返回值以返回您需要返回的任何数据。
发挥作用的第二个方面是软版本化。 Thrift允许稍后增强接口和数据结构,而不会破坏旧服务或客户端。如果您决定这样做
struct Bar { /*some data*/ }
service Foo {
list<Bar> GiveMeTheData()
}
你从根本上切断了这种机制。因为返回的list<Bar>
无法使用新的其他成员进行扩展。在这种情况下,您将不得不添加另一个电话。
相比之下,通过使用包装struct
,可以轻松扩展退货数据,而且付出的代价并不高:
struct Bar { /*some data*/ }
struct FooResult {
1: list<Bar> list
// new members here
}
service Foo {
FooResult GiveMeTheData()
}
此外,后者还允许返回NULL列表,这对于第一个布局是不可能的。