Scala中奇怪的输入错误

Hen*_*son 10 types scala

看看这个:

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
Run Code Online (Sandbox Code Playgroud)

如何定义Container的第二种方式,但第一种方式不适用?这些类型不一样吗?

Did*_*ont 13

这不是错误.Array是不协变的.B是B的子类型,不使Array [B]成为Array [A]的子类型.这与java相反,其中B []是A []的子类型,它是不健全的:

A[] b = new B[1];
b[0] = new (A);
-> ArrayStoreException
Run Code Online (Sandbox Code Playgroud)

所以你的数组[Some [Any]]不是数组[Option [Any]].您必须确保拥有可以使用的数组[选项]

val row2 = Array[Option[Any]](Some(test2), Some(12345))
Run Code Online (Sandbox Code Playgroud)

您还可以在其中一个项目上使用类型abscription:

val row2 = Array(Some(test2): Option[String], Some(12345))
Run Code Online (Sandbox Code Playgroud)

或者,如果您知道您的值为非null,

val row2 = Array(Option(test2), Option(12345))
Run Code Online (Sandbox Code Playgroud)

(这足以在其中一个值上做到这一点)

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])
Run Code Online (Sandbox Code Playgroud)