2012-07-23 81 views
3

我已經定義了以下特點:爲什麼特質方法需要asInstanceOf和類方法不

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) 
    ... 
} 

我的問題是有關在特徵中的「方形」方法的定義中需要「asInstanceOf」。如果我刪除它,我得到以下錯誤:

error: type mismatch; 
found : Felem.this.type (with underlying type Felem[T]) 
required: T 
def square: T = this.mul(this) 
  1. 爲什麼需要它的特質?
  2. 爲什麼在課堂上是不是需要?
  3. 它的費用在執行時間或記憶項什麼?

回答

7

MULT的參數必須是T類型。

當調用mul(this)時,此參數的類型爲Felem[T],該參數不符合也不符合TT符合Felem[T]的附加約束條件。但這不是你想要的,你需要相反的,Felem[T]以符合T

在另一方面,在F2elemT正是F2elem,所以它typechecks(completley無關一個是性狀,並且另一個類)

下面是示例表明,在Felem必須定義確實不進行類型檢查,而且它可能有執行者那裏Felem[T]不符合T

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

該聲明是正確的,F2elem這是T滿足T <: Felem[T]給出。 然而,在square繼承牛逼his.mul(this)將是無效的,多重峯期待T,即F2elem,這是F3elem。他們是無關的。

你可能想要的是,每一個Felem必須像F2elem,那就是T必須是實際的類的類型。您可以使用自我類型強制執行此操作。

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

當你寫的,你說,在每一個執行,執行的類型必須符合T。這樣做,它會進行類型檢查,你將不會被允許實例化F3elem以上:

error: illegal inheritance; self-type F3elem does not conform to Felem[F2elem]'s selftype F2elem class F3elem extends Felem[F2elem] {

+1

感謝自我類型的把戲:-) – acapola 2012-07-23 06:55:18

1

您正在使用T作爲您的方法的參數類型。這意味着無論的T類型是將是在方法所需的類型(因此不需要在類中投,因爲它的類型是什麼是T最初表示)。

如果更改的that類型Felem[T],你不需要投。

2

1)在你的traitthis不是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 = [email protected] 

scala> res1.square 
java.lang.ClassCastException: F3elem cannot be cast to F2elem 

2)在你classthisF2elemT == F2elem,所以thisT

相關問題