2

我目前无法完全理解 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]]正在加剧整个事情。

除了解决这个问题的一些有用的想法之外,我非常感谢任何进一步的阅读链接(尽管我已经阅读了所有关于 SO 的内容)。

4

1 回答 1

2

使用以下测试它是否是一个对象(来自这个问题):

typeOf[Test] <:< typeOf[Singleton]

您可以使用存在类型来获得TypeTag您的特征:

typeOf[MyTrait[M, T] forSome { type M <: MyTrait[M, T] }]

如果您有一个TypeTag[T]in 范围并且绑定如下:

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没有适当的界限。因此,您必须对此进行测试(在此处提供一些帮助):

val mts = typeOf[MyTrait[_,_]].typeSymbol

typeOf[Test].baseType(mts) match {
  case TypeRef(_, _, List(_, t)) if t <:< typeOf[MyEnt] => true
  case _ => false
}
于 2013-06-11T23:22:50.993 回答