2012-07-30 54 views
6

我移動我的第一個步驟,Scala和我想作以下的代碼工作:協變T型發生在不變的位置

trait Gene[+T] { 
    val gene: Array[T] 
} 

編譯器給出的錯誤:covariant type T occurs in invariant position in type => Array[T] of value gene

我知道我可以做這樣的事情:

trait Gene[+T] { 
    def gene[U >: T]: Array[U] 
} 

,而是因爲我需要一個值,這並不能解決問題:pratically什麼,我想說的是:「我不關心的插件ide類型,我知道基因會有一個返回其內容的基因場「。 (這裏的+ T是因爲我想做類似type Genome = Array[Gene[Any]]的東西,然後用它作爲單個基因類的包裝,所以我可以有一個異構數組類型) 是可以在Scala中完成它,或者我只是簡單地錯誤的方法?如果使用不同的結構,比如Scala原生協變類,會更好嗎?

在此先感謝!

P.S .:我也試過類和抽象類而不是特質,但總是相同的結果!

編輯:由迪迪埃杜邦樣的建議,我來到這個代碼:

package object ga { 


    class Gene[+T](val gene: Vector[T]){ 

    def apply(idx: Int) = gene(idx) 

    override def toString() = gene.toString 

    } 

    implicit def toGene[T](a: Vector[T]) = new Gene(a) 

    type Genome = Array[Gene[Any]] 

} 

package test 

import ga._ 

object Test { 
    def main(args: Array[String]) { 
     val g = Vector(1, 3, 4) 

     val g2 = Vector("a", "b") 

     val genome1: Genome = Array(g, g2) 

     println("Genome") 

     for(gene <- genome1) println(gene.gene) 
    } 
} 

所以我覺得現在我可以把和檢索不同類型的數據,並與所有類型使用它們檢查好吃的東西!

回答

9

數組是不變的,因爲你可以寫入它。

假設你做

val typed = new Gene[String] 
val untyped : Gene[Any] = typed // covariance would allow that 
untyped.gene(0) = new Date(...) 

這將崩潰(在您的實例的陣列是[字符串]也不會接受一個Date)。這就是編譯器阻止這種情況的原因。

從那裏,它很大程度上取決於您打算如何處理基因。您可以使用協變類型而不是Array(您可能會考慮Vector),但如果這是您的意圖,那麼這將阻止用戶更改內容。你也可以在這個類裏面有一個數組,只要它聲明爲private [this](這也會使得它很難改變內容)。如果您希望允許客戶端突變基因的內容,則可能無法使Gene協變。

+0

不,我不需要改變它,我確實是關於Vector的。我的主要要求是讓客戶端代碼管理不同的Gene [T]數組,但仍然對操作有類型限制。我知道這很困難,並且仍然處於第一步,也許我只是在思考過於實用,或者過於活躍,但我打算開發更大的東西,這可能是一個要求:自動裝箱和取消裝箱價值。如果你想要,我可以重述這個問題! – 2012-07-30 13:27:19

+0

請做。你做什麼都行不通,但不知道你需要什麼,很難提供更多的幫助。性能是你想要一個數組的原因嗎?客戶期望與Gene [T]的異質集合做什麼? – 2012-07-30 14:23:58

+0

編輯我的答案。請檢閱它,因爲我認爲感謝您的幫助,我找到了解決方案。顯然我會接受你的答案;) – 2012-07-30 15:02:54

2

gene的類型需要在其類型參數中協變。爲了做到這一點,你必須選擇一個不可變的數據結構,例如列表。但是您可以使用scala.collection.immutable包中的任何數據結構。

相關問題