2013-12-16 192 views
1

編輯後面的兩個答案 我想讓下面的Scala代碼編譯。斯卡拉類型覆蓋

abstract class C { 
    type T <: C 
    def x(other: T): (T, T) 
    } 

    class C1 extends C { 
    override type T = C1 
    override def x(other: C1): (C1, C1) = (this, this) 
    } 

    def doSthg(cs1 : List[C]) { 
    val e1 = cs1(0) 
    val e2 = cs1(1) 

    e1.x(e2) 
    } 

但失敗,出現以下消息:

Description Resource Path Location Type 
type mismatch; found : e2.type (with underlying type Chromo[G]) required: e1.C PI3.sc /GA/src/org/jts/ga line 76 Scala Problem 
type mismatch; found : e2.type (with underlying type org.jts.ga.MI2.C) required: e1.T MI2.sc /GA/src/org/jts/ga line 18 Scala Problem 

任何想法?

基本上,我想定義一個像上面C一樣的泛型類,並且在子類(C1)上有正確類型的方法。

直到在soSthg中的C上調用泛型方法爲止都是很好的。

感謝

新的編輯部分

感謝v多少您的答覆。看看下面的代碼,我希望避免asInstanceOf。

abstract class G[T](val t: T) { 
    def ~(): G[T] 
    } 
    abstract class C[T](val g: List[G[T]]) { 
    def x(other: C[T]): (C[T], C[T]) 
    } 

    class G1(override val t: Boolean) extends G[Boolean](t){ 
    override def ~() = new G1(!t) 
    } 

    class C1(override val g: List[G1]) extends C[Boolean](g) { 
    override def x(other: C[Boolean]): (C[Boolean], C[Boolean]) = { 
     val go = other.g.map(e => e.asInstanceOf[G1]) 
     //val go = other.g 
     val nc1 = new C1(go) 
     (nc1, nc1) // for demo 
    } 
    } 

x(other:C [Boolean])的簽名的確是問題。

這會工作:

def doSthg2[T <: C](csl : List[T]) { csl(0).x(csl(1)) } 

如何避免asInstanceOf?

回答

1

有沒有定義Ç& C1作爲問題以上。問題在於你傳遞了一個參數給類型爲C(不是C1)的e1.x,所以違反了你的C1.x方法簽名。

至於編譯器而言:

  1. 你在造型特徵/類C
  2. 裏面doSthg根的類型層次,在丘壑e1 & e2均爲某種類型的層次結構中。對於e1 &e2,唯一確定的事情是e1.typee2.type各自是C的子類型。有沒有保證e1e2是相同類型(或者是彼此的子類型) - 儘管類層次很淺(只有一個子類,C1)。您可以通過在將來的任何時候在新的.class/.jar文件中添加新的子類型C(可能通過此機器上此編譯器的.scala/.java文件生成,或者甚至通過不同機器上的不同編譯器生成!)
  3. 您選擇了您的方法C1.x不靈活 - 它的參數必須是C1類型,而不是任何C。因此,e1.x不能以「任意」e2 <: C作爲參數。

因此,編譯器根據您的設計決策做了正確的事情。解決方案:

  • 允許C1.x採取型C
  • 的論據是doSthg參數List[C1](同時C1的範圍內移動可能doSthg)
+0

的確。像這樣的東西可以工作:def doSthg2 [T <:C](csl:List [T]){csl(0).x(csl(1)) } – jts

10

C1編譯得很好。請注意,您可以在這裏刪除override關鍵字:

class C1 extends C { 
    type T = C1 
    def x(other: C1): (C1, C1) = (this, this) // do you mean (other, this)? 
} 

doSthg就是無效的:你不能證明e2e1.T。這按預期工作:

def doSthg(e1: C)(e2: e1.T) { 
    e1.x(e2) 
} 

或者這樣:

abstract class C { 
    ... 
    def create(): T 
} 

def doSthg(e1: C) { 
    val e2 = e1.create() 
    e1.x(e2) 
} 

的原裝doSthg方法x應該接受C任何實例:

trait C { 
    def x(other: C): (C, C) 
}