我定义了以下特征:
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)
答案 0 :(得分:7)
mult的参数必须是T
类型。
调用mul(this)
时,此参数的类型为Felem[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
的实现者。
F2elem
此声明是正确的,为T
提供的T <: Felem[T]
满足his.mul(this)
。
但是,square
中的继承t T
将无效,mult期望F2elem
,即F3elem
,这是Felem
。他们是无关的。
您可能希望每个F2elem
必须与T
类似,即trait Felem [T <: Felem[T]] { this: T => /* your code */ }
必须是实际类的类型。您可以使用自我类型强制执行此操作。
T
当您编写它时,您声明在每个实现中,实现的类型必须符合{{1}}。这样做,它会进行类型检查,并且你不会被允许在上面实现F3elem:
错误:非法继承;自我型F3elem不符合 Felem [F2elem]的自我型F2elem F3elem课程扩展了Felem [F2elem] {
答案 1 :(得分:2)
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
的实例:
class
2)在this
F2elem
T
和F2elem
== this
,T
为{{1}}。
答案 2 :(得分:1)
您使用T
作为方法的参数类型。这意味着无论T
的类型是什么类型都是方法中所需的类型(因此不需要类中的强制转换,因为它的类型最初由T
表示)。
如果您将that
的类型更改为Felem[T]
,则不需要演员。