协变类型T发生在不变的位置(covariant type T occurs in invariant

2019-07-30 16:15发布

我移动我的第一个步骤,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]
}

但因为我需要一个值,这并不能解决问题:pratically什么,我想说的是:“我不关心类型里面的,我知道,基因将有一个基因场返回其内容”。 (在+ T这里是因为我想要做类似type Genome = Array[Gene[Any]] ,然后用它作为针对单个基因类的包装,所以我可以具有异质阵列型)是否有可能做到这一点在斯卡拉或者我只是采取了错误的做法? 它会更好使用不同的结构,像斯卡拉母语协变类?

提前致谢!

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

所以我想现在我可以把在不同类型的检索数据,并与所有类型检查的好东西使用它们!

Answer 1:

数组是不变的,因为你可以把它写。

假设你做

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

这将崩溃(在您的实例的阵列是[字符串]也不会接受一个Date)。 这就是为什么编译器阻止了。

从那里,这取决于你打算用基因做非常多。 你可以使用一个协变型,而不是Array (你可以考虑Vector ),但会阻止用户对变异的内容,如果这是你的原意。 您还可能有类里的数组,只要它是decladed private [this] (这将使它十分困难的变异内容太)。 如果你想在客户端被允许变异基因的内容,它可能不会有可能使基因协变。



Answer 2:

该类型的gene ,需要在它的类型参数进行协变的。 为实现这一目标是可能的,你必须选择一个不可变的数据结构,例如列表。 但是你可以使用任何数据结构从scala.collection.immutable包。



文章来源: covariant type T occurs in invariant position