我目前无法围绕Scala的TypeTag反射API。在网上找不到很少的信息,所有的试错尝试都无处可寻。
def doStuff[T: TypeTag]( param: String ): SomeStuff[E] =
{
val t = typeOf[T]
if( <t extends one specific Trait from my application and is an object> )
{
<retrieve that companion object and return one of its values>
}
else
{
t match
{
case x if x =:= typeOf[String] => doOtherStuff[String]( param )
case x if x =:= typeOf[Int] => doOtherStuff[Int]( param )
...
}
}
}
与Scala的预定义类型匹配的模式正在运行。但是我没有设法检查提供的泛型参数是否继承了我的特定Trait,然后检索T
后面的实际类的伴随对象。尝试使用直接typeOf[MyTrait[_, T]]
被编译器拒绝,告诉我没有可用于MyTag的TypeTag。我该如何创建它?
此外,Trait令人讨厌的通用签名MyTrait[M <: MyTrait[M, E], E <: Entity[M, E]]
正在加剧整个事情。
除了一些有用的想法来解决这个问题,我非常感谢任何进一步的阅读链接(虽然我已经阅读了所有内容)。
答案 0 :(得分:2)
使用以下内容测试它是否为对象(来自this question):
typeOf[Test] <:< typeOf[Singleton]
您可以使用存在类型来获得特征的TypeTag
:
typeOf[MyTrait[M, T] forSome { type M <: MyTrait[M, T] }]
如果您在范围内有TypeTag[T]
并且绑定如下:
T <: Entity[_,T]
最小例子:
trait Entity[M, E]
trait MyTrait[M <: MyTrait[M, E], E <: Entity[M, E]]
class MyEnt extends Entity[Test, MyEnt]
class Test extends MyTrait[Test, MyEnt]
def getType[T <: Entity[_, T] : TypeTag] =
typeOf[MyTrait[M,T] forSome { type M <: MyTrait[M,T] }]
typeOf[Test] <:< getType[MyEnt]
//| res0: Boolean = true
但是,这不适用于您的情况,因为T
没有正确限制。因此,你必须对此进行测试(在here的帮助下):
val mts = typeOf[MyTrait[_,_]].typeSymbol
typeOf[Test].baseType(mts) match {
case TypeRef(_, _, List(_, t)) if t <:< typeOf[MyEnt] => true
case _ => false
}