为什么trait方法需要asInstanceOf和class方法不需要

aca*_*ola 3 generics scala traits

我已经定义了以下特征:

trait Felem[T <: Felem[T]] {                                               
  def mul(that: T): T
  def square: T = this.mul(this.asInstanceOf[T])                            
}
Run Code Online (Sandbox Code Playgroud)

我还根据这个特性定义了一个类:

class F2elem(val coef: Boolean) extends Felem[F2elem] {
  override def square: F2elem = this.mul(this)
  ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是关于特征中"square"方法定义中"asInstanceOf"的需要.如果我删除它,我会收到以下错误:

error: type mismatch;
found   : Felem.this.type (with underlying type Felem[T])
required: T
def square: T = this.mul(this)
Run Code Online (Sandbox Code Playgroud)
  1. 为什么需要特质?
  2. 为什么课堂上不需要它?
  3. 在执行时间或内存方面是否需要花费任何成本?

Did*_*ont 7

mult的参数必须是类型T.

调用时mul(this),this参数是类型Felem[T],不符合也不符合T.还有T符合的附加约束Felem[T].但这不是你想要的,你需要相反,Felem[T]以符合T.

另一方面,in F2elem,T确实F2elem如此,所以它是typechecks(完全无关,一个是特质而另一个是一个类)

这是一个示例,表明定义Felem必须确实不是类型检查,并且可能有Felem[T] 不符合的实现者T.

class F3elem extends Felem[F2elem] // this is 2, not 3
Run Code Online (Sandbox Code Playgroud)

这个声明是正确的,F2elem这是为了T满足T <: Felem[T].但是,继承的t his.mul(this)in square将是无效的,mult期望a T,即F2elem,这就是F3elem.他们是无关的.

你可能想要的是每个Felem必须是F2elem,那就是T必须是实际类的类型.您可以使用自我类型强制执行此操作.

trait Felem [T <: Felem[T]] { this: T => /* your code */ }
Run Code Online (Sandbox Code Playgroud)

当您编写它时,您声明在每个实现中,实现的类型必须符合T.这样做,它会进行类型检查,并且您不会被允许在上面实现F3elem:

错误:非法继承; 自我型F3elem不符合Felem [F2elem]的自我类型F2elem类F3elem延伸Felem [F2elem] {