Reputation: 3691
I need to have three thrift classes: ThriftClassList, ThriftClass1, ThriftClass2. Depending on some conditions from request I need to pass to ThriftClassList object of class ThriftClass1 or ThriftClass2.
So I need to have some sort of such thrift definition
struct ThriftClassList {
1: required list<?> data
}
But thrift doesn't support such definition, I can only do
struct ThriftClass1List {
1: required list<ThriftClass1> data
}
struct ThriftClass2List {
1: required list<ThriftClass2> data
}
But I don't want to have two four classes, ThriftClass1List and ThriftClass2List are similar, I want to have some sort of wildcard.
Is doing two list classes the only way to solve this problem?
Upvotes: 1
Views: 1294
Reputation: 13411
There is no built-in way to do this with Thrift. Regarding this restriction it may help to keep in mind that Thrift generates code for about 20+ languages. Not all of them do support OOP or comparable concepts, let alone polymorphism or more enhanced concepts like generics.
A possible solution could involve union
s:
struct ListElement {
1: Foo foo
2: Bar bar
// add other elements as needed
}
struct OuterClass {
1: list<ListElement> data
}
The only drawback here is that nothing prevents you from mixing foo and bar in one list instance. If such must be avoided, either add code to verify this at runtime, or define two different lists as you already did in the original question to make it type safe from the beginning. The choice is yours.
Upvotes: 2
Reputation: 5317
Adding to @JensG answer. Another option for "polymorphism" is to just have every type as optional and use a flag field to indicate which are there.
enum PersonType {
CHILD,
ADULT,
EMPLOYEE,
BOSS,
DOCTOR
}
struct Person {
1: i32 personId ,
2: PersonType type, // Tells us which are set
3: double timestamp,
4: optional Child child
5: optional Adult adult
6: optional Employee employee
7: optional Boss boss
8: optional Doctor doctor
}
service API{
Person GetPerson(1: i32 id)
}
then client side you have a factory:
func getPerson(int id) *Person {
p := thrift.GetPerson(1)
switch p.type {
case thrift.CHILD:
return newChild(p)
case thrift.ADULT:
return newAdult(p)
case thrift.BOSS:
panic("Not a person")
}
}
Upvotes: 1