对于Scala中的特征来说,Manifest上的访问似乎很棘手。
这段代码怎么能在scala中编译?
trait SomeTraitOf[+A] { def newInstanceOfA : A = /* necessary code to make it work */ }(相关,它作为参数化类可以正常工作:
class SomeTraitOf[A : Manifest] { def newInstanceOfA(implicit m : Manifest[A]) : A = m.erasure.newInstance.asInstanceOf[A] }但没有协变型参数(+ A))
编辑:真实的东西
sealed trait RootPeerProxy[+A] extends Proxy { def peer: A def self = peer def peerManifest[B >: A](): Option[Manifest[B]] private[scalavaadin] def newInstance() : Option[A] } trait PeerProxy[+A] extends RootPeerProxy[A] { override def peerManifest[B >: A](): Option[Manifest[B]] override def peer(): A = this.newInstance match { case None => {throw new IllegalStateException("oups")} case Some(a) => a } private[scalavaadin] override def newInstance() : Option[A] = peerManifest map { m => m.erasure.newInstance.asInstanceOf[A] } }由于traits不能为参数化特征提供清单,实现特征的类应该,但我没有得到它。
The access on Manifest seems to be tricky from a trait in scala.
How could this code compile in scala ?
trait SomeTraitOf[+A] { def newInstanceOfA : A = /* necessary code to make it work */ }(Related, it works fine as a parametized class :
class SomeTraitOf[A : Manifest] { def newInstanceOfA(implicit m : Manifest[A]) : A = m.erasure.newInstance.asInstanceOf[A] }but not with a covariant type parameter (+A))
Edit : The real stuff
sealed trait RootPeerProxy[+A] extends Proxy { def peer: A def self = peer def peerManifest[B >: A](): Option[Manifest[B]] private[scalavaadin] def newInstance() : Option[A] } trait PeerProxy[+A] extends RootPeerProxy[A] { override def peerManifest[B >: A](): Option[Manifest[B]] override def peer(): A = this.newInstance match { case None => {throw new IllegalStateException("oups")} case Some(a) => a } private[scalavaadin] override def newInstance() : Option[A] = peerManifest map { m => m.erasure.newInstance.asInstanceOf[A] } }Since traits cannot provide manifest for the parametized trait, the class implementing the trait should, but I am not getting it.
最满意答案
关于协方差 :
由于Manifest[A]在参数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] }About covariance:
Since Manifest[A] is invariant in the parameter A, you can't do what you want directly. The usual strategy is to weaken the return type,
trait SomeTraitOf[+A] { def newInstance[B >: A](implicit m: Manifest[B]): B = { m.erasure.newInstance.asInstanceOf[B] } }You can use the trait as follows,
class Parent class Child extends Parent val childBuilder = new SomeTraitOf[Child] {} val parentBuilder: SomeTraitOf[Parent] = childBuilder parentBuilder.newInstance // returns a Parent!About View Bounds:
From your comment below, I guess you're also asking about "view bounds", which are just a concise way of declaring an implicit parameter. Your declaration
class SomeTraitOf[A : Manifest] { ...basically translates to
class SomeTraitOf[A]()(implicit m0: Manifest[A]) { ....Traits can't have view bounds because they can't take any (value) parameters. But that's not really a problem here, because in your example
class SomeTraitOf[A : Manifest] { def newInstanceOfA(implicit m : Manifest[A]) : A = m.erasure.newInstance.asInstanceOf[A] }you're not using the view bound! (You're using the parameter m instead.) If you wanted to use the view bound, you could do it this way:
class SomeTraitOf[A : Manifest] { def newInstanceOfA : A = implicitly[Manifest[A]].erasure.newInstance.asInstanceOf[A] }更多推荐
发布评论