#scala
#scala
Вопрос:
Я совершенно новичок в Scala, так что потерпите меня, пожалуйста! Я выполняю несколько упражнений Scala, и одно из них заключается в создании списка нечетных чисел от 1 до 20. Это довольно прямолинейно, но меня немного смущает тип возвращаемого значения filter
метода для диапазона.
У меня есть следующий блок:
val lst2 = (1 to 20).filter(_ % 2 != 0)
println(lst2)
Результатом этого является:
Вектор(1, 3, 5, 7, 9, 11, 13, 15, 17, 19)
Однако, когда я явно задаю тип lst2
на Vector[Int]
, подобный следующему:
val lst2: Vector[Int] = (1 to 20).filter(_ % 2 != 0)
println(lst2)
Я получаю это:
16: ошибка: несоответствие типов;
найдено: scala.collection.immutable.IndexedSeq[Int]
требуется: Vector[Int] val lst2: Vector[Int] = (от 1 до 20).filter(_ % 2 != 0) ^ найдена одна ошибка
Итак, в чем тут дело? println
Метод просто не выдает мне правильный тип? Как мне заставить метод filter возвращать вектор?
Ответ №1:
Единственная гарантия, предоставляемая filter
of Range
, заключается в том, что он возвращает collection.immutable.IndexedSeq[A]
, поэтому это компилирует:
val lst2: collection.immutable.IndexedSeq[Int] = (1 to 20).filter(_ % 2 == 1)
Во время выполнения lst2
просто получается a Vector[Int]
, но это не гарантируется интерфейсом, поэтому авторы filter
метода фактически оставляют за собой право изменять конкретную реализацию на другую IndexedSeq
, когда им заблагорассудится. Тип Vector
— это деталь реализации, на которую вам не следует полагаться.
Причина, по которой он печатается как Vector(...)
, заключается в том, что это зависит от реализации toString
конкретного экземпляра, который присутствует во время выполнения, а не от статически известного типа (динамическая отправка).
Если вы действительно хотите что-то с типом Vector
, просто добавьте .toVector
:
val lst2: Vector[Int] = (0 to 20).filter(_ % 2 == 1).toVector