繁体   English   中英

为什么特质方法需要asInstanceOf而类方法不需要

[英]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)
  1. 为什么特质需要它?
  2. 为什么在课堂上不需要它?
  3. 就执行时间或内存而言,它会花费什么吗?

参数mult必须为T类型。

调用mul(this) ,this参数的类型为Felem[T] ,该参数不是T且不符合T 还有一个附加约束条件,即T符合Felem[T] 但这不是您想要的,您需要相反的Felem[T]来符合T

另一方面,在F2elemT恰好是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 thisF2elemT == F2elem ,所以thisT

您正在使用T作为方法的参数类型。 这意味着无论T的类型是方法中所需的类型(因此不需要在类中进行强制转换,因为它的类型最初是T表示的)。

如果更改的类型thatFelem[T]你不需要投。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM