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. なぜ特性で必要なのですか?
  2. クラスで必要ないのはなぜですか?
  3. 実行時間やメモリの点でコストはかかりますか?
4

3 に答える 3

7

mult のパラメーターは、タイプでなければなりませんT

を呼び出すときmul(this)、このパラメータは型Felem[T]ではなく、準拠していませんTTに準拠する追加の制約がありますFelem[T]。しかし、これはあなたが望むものではありませFelem[T]T

一方、 inF2elemTまさにF2elemであるため、型チェックを行います (1 つはトレイトで、もう 1 つはクラスとは完全に無関係です)。

 の定義が実際に型チェックしてはならないこと、および に準拠しないFelem実装者を持つことが可能であることを示す例を次に示します。Felem[T]T

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

satisfiesF2elemに対して与えられたこの宣言は正しいです。ただし、継承された t inは無効です。mult は、つまり、およびこれはを期待します。そして、それらは無関係です。TT <: Felem[T]his.mul(this)squareTF2elemF3elem

おそらくあなたが望むのは、 everyFelemが のようF2elemでなければならない、つまり、それがT実際のクラスの型でなければならないということです。これは、自己型で強制できます。

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

あなたがそれを書くとき、あなたはすべての実装において、実装の型が に準拠しなければならないことを述べますT。これを行うと、型チェックが行われ、上記の F3elem をインスタンス化できなくなります。

エラー: 不正な継承です。自己型 F3elem は Felem[F2elem] の自己型 F2elem クラス 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では、そうthisですT.

于 2012-07-23T06:02:34.623 に答える
1

Tメソッドのパラメーターの型として使用しています。これは、 の型が何であれ、Tメソッドで必要な型になることを意味します (その型はT元々 によって示されているため、クラスでキャストする必要はありません)。

の型を に変更するthatFelem[T]、キャストは不要になります。

于 2012-07-23T06:01:01.887 に答える