В СО, я видел вопросы, которые сравнивают Array with Seq, List with Seq и Vector with well, everything. Однако я не понимаю ничего. Когда я должен использовать Seq
над любым из них? Я понимаю, когда следует использовать List
, когда использовать Array
и когда использовать Vector
. Но когда это хорошая идея использовать Seq
, а не любую из перечисленных выше коллекций? Почему я должен использовать trait
, который расширяет Iterable
, а не все конкретные классы, перечисленные выше?Как использование Seq сравнивается с классом List, Array и Vector?
ответ
Вы обычно должны использовать 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
(быстрое выделение памяти). В любом случае, вы должны предпочесть большинство классов верхнего уровня, если вы хотите, чтобы ваша функция была больше polymorphic имеет свой входной параметр, так как Seq
- это общий интерфейс для всех последовательностей. Если вам нужно что-то более общее - вы можете использовать Traversable
или Iterable
.
Принципиальная схема здесь такая же, как на нескольких языках (например, в Java часто следует использовать List вместо ArrayList или Map вместо HashMap). Если вы имеете дело с более абстрактной концепцией Seq, вы должны, особенно когда они являются параметрами методов.
2 основные причины, которые приходят на ум:
1) повторное использование кода. например если у вас есть метод, который принимает foo (s: Seq), его можно повторно использовать для списков и массивов.
2) умение легко передумать. Например. Если вы решите, что List работает хорошо, но внезапно вы осознаете, что вам нужен произвольный доступ и хотите изменить его на массив, если вы определяете List везде, вы будете вынуждены менять его повсюду.
Примечание №1: есть моменты, когда вы могли бы сказать, что Итерабельный над Seq, если ваш метод поддерживает его, и в этом случае я бы склонен быть как можно более абстрактным.
Примечание № 2: Иногда я мог бы склонен не говорить Seq (или быть полностью абстрактным) в моих рабочих библиотеках, даже если бы мог. Например. если бы я сделал что-то, что было бы крайне неэффективным с неправильной коллекцией. Например, делать произвольный доступ - даже если бы я мог написать свой код для работы со списком, это приведет к большой неэффективности.
Возможно, связано: http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface –