13

私はScalaで最初のステップを進めており、次のコードを機能させたいと思っています。

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]
}

しかし、値が必要なため、これでは問題は解決しません。実際に私が言おうとしているのは、「内部のタイプは気にしない。遺伝子には、その内容を返す遺伝子フィールドがあることを知っている」ということです。(ここでの+ Tは、次のようなことをtype Genome = Array[Gene[Any]]行い、それを単一の遺伝子クラスに対するラッパーとして使用して、異種の配列型を持つことができるためです)Scalaでそれを行うことは可能ですか、それとも単に間違ったアプローチを取っていますか?Scalaのネイティブ共変クラスのように、別の構造を使用する方がよいでしょうか?

前もって感謝します!

PS:トレイトではなく、クラスと抽象クラスも試しましたが、常に同じ結果になります。

編集:ディディエデュポンによる親切な提案で私はこのコードに来ました:

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

だから今、私はさまざまなタイプのデータを入れて取得し、それらをすべてのタイプチェックグッズで使用できると思います!

4

2 に答える 2

13

配列は書き込むことができるため、不変です。

あなたがすることを仮定します

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

これはクラッシュします(インスタンス内の配列はArray [String]であり、日付を受け入れません)。これが、コンパイラがそれを防ぐ理由です。

そこから、それはあなたがジーンで何をしようとしているのかに大きく依存します。Array(検討するかもしれませんが)の代わりに共変型を使用することもできますがVector、これが意図したものである場合、ユーザーがコンテンツを変更することはできません。クラス内に配列が含まれている場合もありますprivate [this](これにより、コンテンツの変更も非常に困難になります)。クライアントが遺伝子のコンテンツを変更できるようにしたい場合は、遺伝子を共変にすることはおそらく不可能です。

于 2012-07-30T13:09:00.357 に答える
3

タイプはgene、タイプパラメーターで共変である必要があります。それを可能にするには、リストなどの不変のデータ構造を選択する必要があります。scala.collection.immutableただし、パッケージの任意のデータ構造を使用できます。

于 2012-07-30T13:08:17.427 に答える