Это не ошибка. 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 является ковариантным (List [B] - это List [A], если B - это 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])