О ковариации :
Поскольку Manifest[A]
инвариантен в параметре A
, вы не можете делать то, что хотите, напрямую.Обычная стратегия состоит в том, чтобы ослабить тип возвращаемого значения,
trait SomeTraitOf[+A] {
def newInstance[B >: A](implicit m: Manifest[B]): B = {
m.erasure.newInstance.asInstanceOf[B]
}
}
Вы можете использовать черту следующим образом:
class Parent
class Child extends Parent
val childBuilder = new SomeTraitOf[Child] {}
val parentBuilder: SomeTraitOf[Parent] = childBuilder
parentBuilder.newInstance // returns a Parent!
О границах просмотра :
Из вашего комментария ниже, я полагаю, вы также спрашиваете о «границах просмотра», которые являются лишь кратким способом объявления неявного параметра.Ваша декларация
class SomeTraitOf[A : Manifest] { ...
в основном переводится в
class SomeTraitOf[A]()(implicit m0: Manifest[A]) { ....
Черты не могут иметь границы просмотра, потому что они не могут принимать никаких (значений) параметров.Но на самом деле это не проблема, потому что в вашем примере
class SomeTraitOf[A : Manifest] {
def newInstanceOfA(implicit m : Manifest[A]) : A =
m.erasure.newInstance.asInstanceOf[A]
}
вы не используете границы представления!(Вместо этого вы используете параметр m
.) Если вы хотите использовать связанный вид, вы можете сделать это следующим образом:
class SomeTraitOf[A : Manifest] {
def newInstanceOfA : A =
implicitly[Manifest[A]].erasure.newInstance.asInstanceOf[A]
}