是否可以使用TypeTag来实现mixin类型?

时间:2015-11-25 11:23:31

标签: scala reflection

重用https://stackoverflow.com/a/18499493/4936026,我写道:

def newInstance[T: TypeTag]: T = {
  val tpe = typeOf[T]

  def fail = throw new IllegalArgumentException(s"Cannot instantiate $tpe")

  val noArgConstructor = tpe.member(termNames.CONSTRUCTOR) match {
    case symbol: TermSymbol =>
      symbol.alternatives.collectFirst {
        case constr: MethodSymbol if constr.paramLists == Nil || constr.paramLists == List(Nil) => constr
      } getOrElse fail

    case NoSymbol => fail
  }
  val classMirror = typeTag[T].mirror.reflectClass(tpe.typeSymbol.asClass)
  classMirror.reflectConstructor(noArgConstructor).apply().asInstanceOf[T]
}

但是,它似乎与mixin类型无法正常工作。确实,以下代码:

class B { def m = 0 }

trait A extends B { override def m = super.m + 1 }

val x = newInstance[B with A]

生成(使用scala 2.11.7编译的代码)

java.lang.IllegalArgumentException: Cannot instantiate B with A

mixin类型不是Scala类型代数的一部分吗?

1 个答案:

答案 0 :(得分:0)

  

mixin类型不是Scala类型代数的一部分吗?

是的,他们是。他们只是没有构造函数。当你在代码中编写new B with A时,你并没有真正实例化B with A,而是由的编译器创建的一个新的匿名类有一个构造函数。如果您只是试图在不涉及mixin的情况下实例化特征,也会发生同样的情况。