[英]why trait method needs asInstanceOf and class method don't
I have defined the following trait: 我定义了以下特征:
trait Felem[T <: Felem[T]] {
def mul(that: T): T
def square: T = this.mul(this.asInstanceOf[T])
}
I also define a class based on this trait: 我还基于此特征定义了一个类:
class F2elem(val coef: Boolean) extends Felem[F2elem] {
override def square: F2elem = this.mul(this)
...
}
My questions are about the need of "asInstanceOf" in the definition of the "square" method in the trait. 我的问题是有关特征中“ square”方法的定义中是否需要“ asInstanceOf”的。 If I remove it, I get the following error:
如果删除它,则会出现以下错误:
error: type mismatch;
found : Felem.this.type (with underlying type Felem[T])
required: T
def square: T = this.mul(this)
The parameter of mult must be of type T
. 参数mult必须为
T
类型。
When calling mul(this)
, the this parameter is of type Felem[T]
, which is not and does not conform to T
. 调用
mul(this)
,this参数的类型为Felem[T]
,该参数不是T
且不符合T
There is the additional constraint that T
conforms to Felem[T]
. 还有一个附加约束条件,即
T
符合Felem[T]
。 But this is not what you want, you would need the opposite, Felem[T]
to conform to T
. 但这不是您想要的,您需要相反的
Felem[T]
来符合T
On the other hand, in F2elem
, T
is exactly F2elem
, so it typechecks (completley unrelated to one being a trait and the other one a class) 另一方面,在
F2elem
, T
恰好是F2elem
,因此它进行类型检查(与一个无关的完全性是一个特征,另一个完全无关)。
Here is example to show that the definition in Felem
must indeed not typecheck, and that it is possible to have implementors where Felem[T]
does not conform to T
. 这是一个示例,说明
Felem
中的定义确实不能进行类型检查,并且可能有Felem[T]
不符合T
。
class F3elem extends Felem[F2elem] // this is 2, not 3
This declaration is correct, F2elem
which is given for T
satisfies T <: Felem[T]
. 这个声明是正确的,为
T
给出的F2elem
满足T <: Felem[T]
。 However, an inherited t his.mul(this)
in square
would be invalid, mult expect a T
, that is F2elem
, and this is F3elem
. 但是,以
square
继承的t his.mul(this)
将是无效的,多期待一个T
,即F2elem
,这是F3elem
。 And they are unrelated. 它们是无关的。
What you probably want is that every Felem
must be like F2elem
, that is that T
must be the type of the actual class. 您可能想要的是每个
Felem
必须像F2elem
一样,也就是说T
必须是实际类的类型。 You can enforce this with a self type. 您可以使用自我类型来强制实施。
trait Felem [T <: Felem[T]] { this: T => /* your code */ }
When you write that, you state that in every implementation, the type of the implementation must conform to T
. 在编写该代码时,您要声明在每个实现中,实现的类型必须符合
T
Doing that, it will typecheck, and you will not be allowed to instanciate F3elem above : 这样做,它将进行类型检查,并且您将无法实例化上面的F3elem:
error: illegal inheritance;
错误:非法继承; self-type F3elem does not conform to Felem[F2elem]'s selftype F2elem class F3elem extends Felem[F2elem] {
自类型F3elem不符合Felem [F2elem]的自类型F2elem类F3elem扩展了Felem [F2elem] {
1) In your trait
this
is not an instance of T
: 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) In your class
this
is F2elem
and T
== F2elem
, so this
is T
. 2)在您的
class
this
是F2elem
和T
== F2elem
,所以this
是T
You're using T
as your method's parameter type. 您正在使用
T
作为方法的参数类型。 This means that whatever the type of T
is will be the type that's required in the method (hence not needing the cast in the class, since its type is what is signified by T
originally). 这意味着无论
T
的类型是方法中所需的类型(因此不需要在类中进行强制转换,因为它的类型最初是T
表示的)。
If you change the type of that
to Felem[T]
, you will not need the cast. 如果更改的类型
that
到Felem[T]
你不需要投。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.