Как мне работать с коллекциями Scala в целом? - PullRequest
4 голосов
/ 22 декабря 2011

Я понял, что мой типичный способ передачи коллекций Scala может использовать некоторое улучшение.

def doSomethingCool(theFoos: List[Foo]) = { /* insert cool stuff here */ }

// if I happen to have a List
doSomethingCool(theFoos)

// but elsewhere I may have a Vector, Set, Option, ...
doSomethingCool(theFoos.toList)

Я склонен писать свои библиотечные функции, чтобы в качестве типа параметра взять List, но я 'Я уверен, что есть что-то более общее, что я могу сделать, чтобы избежать всех случайных вызовов .toList, которые есть в коде приложения.Это особенно раздражает, так как моей doSomethingCool функции обычно нужно только вызывать map, flatMap и filter, которые определены для всех типов коллекций.

Какие у меня есть варианты для этогоболее общий '?

Ответы [ 2 ]

6 голосов
/ 22 декабря 2011

Вот более общие черты, каждая из которых расширяет предыдущую:

  • GenTraversableOnce
  • GenTraversable
  • GenIterable
  • GenSeq

Приведенные выше признаки не указывают, является ли сбор последовательным или параллельным.Если ваш код требует, чтобы вещи выполнялись последовательно (как правило, если ваш код имеет побочные эффекты любого рода), они слишком общие для него.

Следующие черты требуют последовательного выполнения:

  • TraversableOnce
  • Traversable
  • Iterable
  • Seq
  • LinearSeq

Первый, TraversableOnce, позволяет вам вызывать только один метод в коллекции.После этого коллекция была «использована».В обмен на это достаточно универсально, чтобы принимать итераторы, а также коллекции.

Traversable - довольно общая коллекция, которая имеет большинство методов.Однако есть некоторые вещи, которые он не может сделать, и в этом случае вам нужно перейти к Iterable.

Все Iterable реализуют метод iterator, который позволяет вам получить Iterator для этогоколлекция.Это дает ему возможность для нескольких методов, отсутствующих в Traversable.

A Seq[A] реализует функцию Int => A, что означает, что вы можете получить доступ к любому элементу по его индексу.Это не гарантирует эффективности, но это гарантия того, что каждый элемент имеет индекс, и что вы можете делать предположения о том, каким будет этот индекс.Сравните это с Map и Set, где вы не можете сказать, что такое индекс элемента.

A LinearSeq - это Seq, обеспечивающий быстрый head, tail, isEmpty и готовьтесь.Это как можно ближе к List без фактического использования List явно.

В качестве альтернативы, вы можете иметь IndexedSeq, который имеет быстрый индексированный доступ (что-то List не делаетпредоставить).

См. также этот вопрос и этот FAQ на его основе.

4 голосов
/ 22 декабря 2011

Наиболее очевидным является использование Traversable в качестве наиболее общей черты, которая будет иметь нужные вам плюсы. Тем не менее, я думаю, что вы, как правило, лучше придерживаться:

  • Seq
  • IndexedSeq
  • Set
  • Map

A Seq покроет List, Vector и т. Д., IndexedSeq покроет Vector и т. Д. И т. Д. Я обнаружил, что не использую Iterable, потому что мне часто нужно (или хочется) знать размер то, что у меня есть, и обратно pre scala-2.8 Iterable не предоставило доступа к этому , поэтому мне все равно приходилось превращать вещи в последовательности!

Похоже, Traversable и Iterable теперь имеют size методы, так что, возможно, я должен вернуться к их использованию! Конечно, вы можете начать «сходить с ума» с GenTraversableOnce, но это вряд ли поможет улучшить читаемость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...