Почему набор scala приводится к вектору вместо списка? - PullRequest
0 голосов
/ 31 января 2020

Интересно, почему Set[A] преобразуется в Vector[A], если я запрашиваю подкласс Seq[A]? Чтобы проиллюстрировать это, возьмем следующий пример:

val A = Set("one", "two")
val B  = Set("one", "two", "three")

def f(one: Seq[String], other : Seq[String]) = {
  one.intersect(other) match {
    case head :: tail => head
    case _ => "unknown"
  }
}

f(A.to, B.to)

Эта функция вернет «неизвестно» вместо единицы. Причина в том, что A.to будет приведено к Vector[String]. Оператор cons (::) не определен для Векторов, но для Списков, поэтому применяется второй случай и возвращается «неизвестно». Чтобы решить эту проблему, я мог бы использовать оператор +:, который определен для всех Seqs, или преобразовать Set в список (A.to[List]). Итак, мой (academi c) вопрос:

Почему A.to возвращает Вектор. По крайней мере, в соответствии с scala документами реализация по умолчанию Seq равна LinearSeq, а по умолчанию это List. Что я не так понял?

1 Ответ

5 голосов
/ 01 февраля 2020

Поскольку это возможно, вы зависите от деталей реализации класса среды выполнения, а не от гарантий информации типа времени компиляции. Метод to или toSeq может свободно возвращать все, что проверяет тип, он может даже генерировать случайное число и выбирать конкретный класс на основе этого числа, так что вы можете получить Список что-то другое Вектор или любой другой. Это может даже определиться с базой операционной системы. Конечно, я здесь педанти c и, надеюсь, они этого не делают, но я хочу сказать, что мы не можем объяснить, что именно делает реализация, и она может измениться в будущем.

Кроме того, "реализация по умолчанию Seq представляет собой List " , применяется только в конструкторе. И снова, они могут изменить это в любой момент.

Итак, если вы хотите Список , попросите Список , а не Seq .

...