scala - Scala 中的奇怪输入错误

标签 scala types

看看这个:

scala> class Container(val rows: Iterable[Iterable[Option[Any]]]) {} 
defined class Container

scala> val row1 = Array(Some("test"),Some(1234))
row1: Array[Some[Any]] = Array(Some(test), Some(1234))

scala> val row2 = Array(Some("test2"), Some(12345))
row2: Array[Some[Any]] = Array(Some(test2), Some(12345))

scala> val listtest = List(row1, row2)
listtest: List[Array[Some[Any]]] = List(Array(Some(test), Some(1234)), Array(Some(test2), Some(12345)))

scala> val test = new Container(listtest)
<console>:11: error: type mismatch;
 found   : List[Array[Some[Any]]]
 required: Iterable[Iterable[Option[Any]]]
       val test = new Container(listtest)
                                ^

scala> val test = new Container(List(row1,row2))
test: Container= Container@600a08

为什么以第二种方式定义 Container 而第一种方式不起作用?类型不一样吗?

最佳答案

这不是错误。 Array不是协变的。 B 作为 B 的子类型不会使 Array[B] 成为 Array[A] 的子类型。这与java相反,其中B[]是A[]的子类型,这是不合理的:

A[] b = new B[1];
b[0] = new (A);
-> ArrayStoreException

所以你的 Array[Some[Any]] 不是 Array[Option[Any]]。你必须确保你有一个 Array[Option],你可以用它来做
val row2 = Array[Option[Any]](Some(test2), Some(12345))

您还可以在其中一项上使用类型归属:
val row2 = Array(Some(test2): Option[String], Some(12345))

或者如果你知道你的值是非空的,
val row2 = Array(Option(test2), Option(12345))

(在其中一个值上做到这一点就足够了)
List ,另一方面是协变的,这就是它起作用的原因。

不幸的是,更精确的类型Some推断,您希望将某事物的类型称为 Some 是非常罕见的。 (或 None)而不是 Option .

编辑 抱歉,看起来我完全没有捕获重点,关于为什么会有不同。 Array不是协变的,但 Iterable 是。所以看起来Array[B]虽然不是 Array[A] , 应该是 Iterable[A] ,那么一切都应该正常工作。如果 Array 是 Iterable 的子类型,情况就会如此。不是,是JVM自带的,不能做扩展Iterable .隐式转换为 WrappedArray ,这是一个 Iterable .

当你写 val l = List(row1, row2) ,没有理由应用这种转换。它尽可能精确地键入列表。那么 List 是协变的(如果 B 是 A,则 List[B] 是 List[A])这一事实不会在我们没有 B 是 A 但 B 隐式转换为 A 时出现。

另一方面,当你写 val l: List[Iterable[A]] = List(x,y) 然后 List(...) 函数需要 Iterable[A] 参数,此时它会寻找隐式转换.

仍然不是错误,但比我想象的要棘手。也许你可以做一个
class Container[T <% Iterable[Option[Any]]](val rows: Iterable[T])

关于scala - Scala 中的奇怪输入错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7281716/

相关文章:

Java 泛型 : Multiple Inheritance in Bounded Type Parameters <T extends A & I>

eclipse - 在IntelliJ IDEA 10中显示 "raw type"警告列表

scala - 如何在Scala中返回None

Scala 下界的行为并不符合我的预期

scala - 带参数扩展类

scala - Akka Actor如何仅处理最新消息

java - 如何使用 ScalaCheck 测试 Java 程序?

python - 在PYTHON中将两个不同数据类型的一维数组组合成1个二维数组

scala - 为混合特性的所有类构建操作

objective-c - 需要帮助将 MPMediaItemPropertyPersistentID 转换为字符串并再次转换回来