如何为Thrift类绕过或满足Scala通用类型

问题描述 投票:0回答:1

我正在尝试编写一个通用的scala实用程序函数来处理Apache Thrift生成的Java类。 Thrift生成的所有Java类都使用以下签名扩展TBase接口:

public interface TBase<T extends TBase<?,?>, F extends TFieldIdEnum>

这在制造通用节俭实用程序功能时总是被证明是有问题的,在Java世界中,我通常通过使用@SuppressWarnings("rawtypes")来解决此问题,因为我知道我正确地处理了它,而忽略了编译器告诉我可以做到的事情,所以,' t验证匹配的类型。

在scala世界中,我似乎没有奢侈或无视这些类型,并且遇到了无法确定如何满足通用类型要求的情况。

因此,我创建了自己的函数,该函数将给定的非节俭对象转换为所请求的Thrift类的实例,其签名类似于:

def myFunc[T <: TBase[T, E], E<: TFieldIdEnum](obj: Any, clazz: Class[T]): T = {

所以我在这里的问题是要调用此函数,我必须做类似的事情:

myFunc[MyThriftClass,MyThriftClass._Fields]( obj, classOf[MyThriftClass] )

没有明确指定第二个类型参数,编译将失败并显示:

error: inferred type arguments [MyThriftClass,Nothing] do not conform to method myFunc's type parameter bounds [T <: org.apache.thrift.TBase[T,E],E <: org.apache.thrift.TFieldIdEnum]
    myFunc( null, classOf[MyThriftClass])
    ^
error: type mismatch;
found   : Class[MyThriftClass](classOf[MyThriftClass])
required: Class[T]
   myFunc( null, classOf[MyThriftClass])

当我传递两个类型参数时,尽管我希望只需要传递类,但一切都正常。

但是如果我在编译时不知道类型,我似乎无法弄清楚如何使它工作。

例如,节俭元数据是通过FieldValueMetaData对象定义的,当有子结构时,提供的元数据对象是StructMetaData,其中包含一个字段

public final Class<? extends TBase> structClass;

鉴于此类缺少类型参数,我不知道如何在满足通用类型约束的情况下使用它来调用我的方法。在递归的情况下,我设法通过将substruct类转换为Class[T]的实例来绕过它,这不是正确的,因为它是父类型而不是子类型,但是由于类型擦除,它使编译器满意并在运行时工作。但是,如果我还没有要转换的泛型类型,那么我可能不知道该如何处理这种情况,除了可能是一种非常hacky的方法外,我将其转换为TBase类的某些虚假外壳只是为了使编译器满意。] >

是否有适当的方法来进行设置,以使编译器对实类型感到满意?另外,还有一种方法可以像我在纯Java中使用@SuppressWarnings("rawtypes")一样绕过此方法。否则,也许我只需要将此逻辑移植到Java上,并从Scala调用它即可使一切变得愉快。在这样做之前,我要么想了解我所缺少的东西,要么想知道为什么我想要的东西是不可能的。

我正在尝试编写一个通用的scala实用程序函数来处理Apache Thrift生成的Java类。 Thrift生成的所有Java类都使用以下签名扩展TBase接口:...

java scala generics thrift
1个回答
0
投票

简短的答案,可能符合您的目的。

© www.soinside.com 2019 - 2024. All rights reserved.