3

我已经定义了以下特征:

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. 为什么在 trait 中需要它?
  2. 为什么课堂上不需要它?
  3. 它在执行时间或内存方面有什么成本吗?
4

3 回答 3

7

mult 的参数必须是类型T

调用mul(this)时this参数是类型Felem[T],不符合也不符合T。存在T符合的附加约束Felem[T]。但这不是您想要的,您需要相反,Felem[T]才能符合T.

另一方面, in F2elem, Tis正是F2elem,所以它会进行类型检查(完全与一个是特征而另一个是类无关)

下面是一个示例,说明Felem必须确实不进行类型检查,并且可能有实现者 whereFelem[T] 不符合T.

class F3elem extends Felem[F2elem] // this is 2, not 3

这个声明是正确的,F2elem它是为T满足而给出的T <: Felem[T]。但是,继承的 t his.mul(this)insquare将是无效的,多期望 a T,即F2elem,而 this 是F3elem。它们是无关的。

您可能想要的是 every Felemmust be like F2elem,即T必须是实际类的类型。您可以使用 self 类型强制执行此操作。

trait Felem [T <: Felem[T]] { this: T => /* your code */ }

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

错误:非法继承;self-type F3elem 不符合 Felem[F2elem] 的 selftype F2elem class F3elem extends Felem[F2elem] {

于 2012-07-23T06:01:42.433 回答
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

2)在你的class thisisF2elemT==F2elem中,所以thisT

于 2012-07-23T06:02:34.623 回答
1

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

如果将类型更改thatFelem[T],则不需要演员表。

于 2012-07-23T06:01:01.887 回答