[英]why trait method needs asInstanceOf and class method don't
我定义了以下特征:
trait Felem[T <: Felem[T]] {
def mul(that: T): T
def square: T = this.mul(this.asInstanceOf[T])
}
我还基于此特征定义了一个类:
class F2elem(val coef: Boolean) extends Felem[F2elem] {
override def square: F2elem = this.mul(this)
...
}
我的问题是有关特征中“ square”方法的定义中是否需要“ asInstanceOf”的。 如果删除它,则会出现以下错误:
error: type mismatch;
found : Felem.this.type (with underlying type Felem[T])
required: T
def square: T = this.mul(this)
参数mult必须为T
类型。
调用mul(this)
,this参数的类型为Felem[T]
,该参数不是T
且不符合T
还有一个附加约束条件,即T
符合Felem[T]
。 但这不是您想要的,您需要相反的Felem[T]
来符合T
另一方面,在F2elem
, T
恰好是F2elem
,因此它进行类型检查(与一个无关的完全性是一个特征,另一个完全无关)。
这是一个示例,说明Felem
中的定义确实不能进行类型检查,并且可能有Felem[T]
不符合T
。
class F3elem extends Felem[F2elem] // this is 2, not 3
这个声明是正确的,为T
给出的F2elem
满足T <: Felem[T]
。 但是,以square
继承的t his.mul(this)
将是无效的,多期待一个T
,即F2elem
,这是F3elem
。 它们是无关的。
您可能想要的是每个Felem
必须像F2elem
一样,也就是说T
必须是实际类的类型。 您可以使用自我类型来强制实施。
trait Felem [T <: Felem[T]] { this: T => /* your code */ }
在编写该代码时,您要声明在每个实现中,实现的类型必须符合T
这样做,它将进行类型检查,并且您将无法实例化上面的F3elem:
错误:非法继承; 自类型F3elem不符合Felem [F2elem]的自类型F2elem类F3elem扩展了Felem [F2elem] {
1)在您的trait
this
不是T
的实例:
scala> trait Felem[T <: Felem[T]] {
| def mul(that: T): T = that
| def square: T = this.mul(this.asInstanceOf[T])
| }
defined trait Felem
scala> class F2elem extends Felem[F2elem]
defined class F2elem
scala> class F3elem extends Felem[F2elem]
defined class F3elem
scala> new F3elem()
res1: F3elem = F3elem@2e0b08f1
scala> res1.square
java.lang.ClassCastException: F3elem cannot be cast to F2elem
2)在您的class
this
是F2elem
和T
== F2elem
,所以this
是T
您正在使用T
作为方法的参数类型。 这意味着无论T
的类型是方法中所需的类型(因此不需要在类中进行强制转换,因为它的类型最初是T
表示的)。
如果更改的类型that
到Felem[T]
你不需要投。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.