[英]existential types
(更新:简化了代码,并说明了为什么它应该工作)
如何修复此代码?:
case class Sub[B <: Seq[_] : Manifest](b: B) {
def foo[B2 >: B <: Seq[_] : Manifest](other: Sub[B2]) : B2 = {
println(manifest[B])
println(manifest[B2])
// next line doesn't compile
// other.b ++ b
other.b
}
}
如果我取消注释other.b ++ b
行,我会收到错误消息:
<console>:13: error: Cannot construct a collection of type That with elements of type Any based on a collection of type Repr.
other.b ++ b
^
如果我发表评论,代码会编译并运行它:
scala> Sub(List(1,2)).foo(Sub(Seq(4,5)))
scala.collection.immutable.List[Int]
scala.collection.Seq[Int]
res0: Seq[Int] = List(4, 5)
所以编译器知道元素的类型是List[Int]
和Seq[Int]
。 连接它们应该没有问题。
注意:我想保留“B2 >: B”的使用,因为我需要推断它。
此时您已经丢失了 Seq[_] 的类型,因此您可以获得的唯一可能的 B 是 Seq[Any]...因此,您可以安全地将 b 归于 Seq[Any] (b: Seq[Any] ]) ++ b2。
仅仅因为您在 B <: Seq[_] 中保留了 B 并不意味着您可以从序列中恢复存在类型。
如果您不依赖于使用存在类型,这应该有效:
case class Sub[T, B[X] <: Seq[X]](b: B[T]) {
def foo[B2[X] <: Seq[X]](other: Sub[T,B2]) =
other.b ++ b
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.