由于某种原因,我无法创建一个actor(这是我的类层次结构的简单版本):
abstract class Class1[T <: Class2[_]: ClassTag] extends Actor {
//....
val res = List(1, 2, 3) map { x => context actorOf Props(new T(x)) } // error
}
abstract class Class2[U <: Class3 : ClassTag](a: Int) extends Actor { ... }
abstract class Class3(b: Int) extends Actor
但是有一个错误说class type required but T found
。
答案 0 :(得分:9)
您无法使用类型参数new T(x)
来呼叫T
。 T
可能没有这样的构造函数:
class WithoutSuchConstructor extends Class2[Class3](1)
您应该明确指定创建T
的方法:
abstract class Class1[T <: Class2[_]: ClassTag] extends Actor {
//....
def createT(i: Int): T
val res = List(1, 2, 3) map { x => context actorOf Props(createT(x)) }
}
可替换地:
abstract class Class1[T <: Class2[_]: ClassTag](createT: Int => T) extends Actor {
//....
val res = List(1, 2, 3) map { x => context actorOf Props(createT(x)) }
}
答案 1 :(得分:5)
我使用的一种方法涉及创建一个'instantiator'特征,可用于创建存在隐式实例化器的类型实例:
trait Instantiator[+A] {
def apply(): A
}
object Instantiator {
def apply[A](create: => A): Instantiator[A] = new Instantiator[A] {
def apply(): A = create
}
}
class Foo() { ... }
object Foo {
implicit val instantiator: Instantiator[Foo] = Instantiator { new Foo() }
}
// def someMethod[A]()(implicit instantiator: Instantiator[A]): A = {
def someMethod[A : Instantiator](): A = {
val a = implicitly[Instantiator[A]].apply()
...
}
someMethod[Foo]()
答案 2 :(得分:1)
我认为这是因为JVM限制也被称为“类型擦除”。 http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
另见“无法创建类型参数的实例” http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html
顺便说一句C#允许你写:
new T()
定义限制时
where T: new()
但遗憾的是构造函数必须是无参数的