Чем отличается использование Seq от списка, массива и вектора?

В SO я видел вопросы, которые сравнивают Array с Seq, Список с последовательностью и Вектор со всем. Хотя я не понимаю одного. Когда мне на самом деле следует использовать Seq поверх любого из них? Я понимаю, когда использовать List, когда использовать Array и когда использовать Vector. Но когда лучше использовать Seq, а не любую из перечисленных выше коллекций? Почему я должен использовать trait, который расширяет Iterable, а не все конкретные классы, перечисленные выше?


person Core_Dumped    schedule 22.01.2015    source источник
comment
Вероятно, связано: stackoverflow.com/questions/383947/   -  person Gábor Bakos    schedule 22.01.2015


Ответы (2)


Обычно вы должны использовать Seq в качестве входного параметра. для метода или класса, определенного для последовательностей в целом (просто общего, не обязательно общего):

def mySort[T](seq: Seq[T]) = ...
case class Wrapper[T](seq: Seq[T]) 
implicit class RichSeq[T](seq: Seq[T]) { def mySort = ...}

Итак, теперь вы можете передать любую последовательность (например, Vector или List) в mySort.

Если ваш алгоритм заботится о сложности - вы можете конкретизировать его до IndexedSeq (быстрый случайный доступ к элементам) или LinearSeq (быстрое выделение памяти). В любом случае, вам следует отдавать предпочтение классу самого верхнего уровня, если вы хотите, чтобы ваша функция была более полиморфна имеет входной параметр, так как Seq является общим интерфейсом для всех последовательностей. Если вам нужно что-то более общее, вы можете использовать Traversable или Iterable.

person dk14    schedule 22.01.2015

Принцип здесь тот же, что и в ряде языков (например, в Java часто следует использовать List вместо ArrayList или Map вместо HashMap). Если вы можете иметь дело с более абстрактной концепцией Seq, вы должны это сделать, особенно когда они являются параметрами методов.

2 основные причины, которые приходят на ум:

1) повторное использование вашего кода. например если у вас есть метод, который принимает foo(s:Seq), его можно повторно использовать для списков и массивов.

2) способность легко передумать. Например. Если вы решите, что List работает хорошо, но вдруг поймете, что вам нужен произвольный доступ, и захотите изменить его на Array, если вы везде определяли List, вам придется изменить его везде.

Примечание № 1: бывают случаи, когда вы можете сказать Iterable вместо Seq, если ваш метод поддерживает это, и в этом случае я склонен быть как можно более абстрактным.

Примечание № 2: Иногда я мог бы не говорить Seq (или быть полностью абстрактным) в своих рабочих библиотеках, даже если бы мог. Например. если бы я сделал что-то, что было бы крайне неэффективно с неправильной коллекцией. Например, при выполнении произвольного доступа - даже если бы я мог написать свой код для работы со списком, это привело бы к значительной неэффективности.

person Bruce Lowe    schedule 22.01.2015