Vin*_*gio 9 scala invariants covariance
我正在移动我在Scala的第一步,我想使以下代码工作:
trait Gene[+T] {
val gene: Array[T]
}
Run Code Online (Sandbox Code Playgroud)
编译器给出的错误是: covariant type T occurs in invariant position in type => Array[T] of value gene
我知道我可以这样做:
trait Gene[+T] {
def gene[U >: T]: Array[U]
}
Run Code Online (Sandbox Code Playgroud)
但这并没有解决问题,因为我需要一个价值:实际上我想说的是"我不关心内部类型,我知道基因会有一个返回其内容的基因字段".(这里的+ 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]]
}
Run Code Online (Sandbox Code Playgroud)
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)
}
}
Run Code Online (Sandbox Code Playgroud)
所以我现在认为我可以放置和检索不同类型的数据,并将它们用于所有类型检查好东西!
Did*_*ont 13
数组是不变的,因为你可以写入它.
假设你这样做
val typed = new Gene[String]
val untyped : Gene[Any] = typed // covariance would allow that
untyped.gene(0) = new Date(...)
Run Code Online (Sandbox Code Playgroud)
这会崩溃(你的实例中的数组是一个数组[String]并且不接受Date).这就是编译器阻止这种情况的原因.
从那里,它很大程度上取决于你打算用什么做基因.您可以使用协变类型而不是Array
(您可能会考虑Vector
),但这会阻止用户改变内容,如果这是您想要的.你可能在类中也有一个Array,只要它被声明private [this]
(这也会很难改变内容).如果您希望允许客户端改变Gene的内容,则可能无法使Gene协变.
归档时间: |
|
查看次数: |
5871 次 |
最近记录: |