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)
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] {