Я рассмотрел этот вопрос, но до сих пор не понимаю разницы между чертами Iterable и Traversable. Кто-нибудь может объяснить?
scala
scala-collections
Рахул
источник
источник
Traversable
в Scala 2.13 (она до сих пор хранится в качестве псевдонима для уходящегоIterable
до 2.14)Ответы:
Проще говоря, итераторы сохраняют состояние, а обходные пути - нет.
Traversable
Имеет один абстрактный метод:foreach
. Когда вы вызываетеforeach
, коллекция будет кормить переданную функцию всеми элементами, которые она хранит, один за другим.С другой стороны, у an
Iterable
есть абстрактный методiterator
, который возвращаетIterator
. Вы можете позвонитьnext
по принципу ,Iterator
чтобы получить следующий элемент в момент вашего выбора. Пока вы этого не сделаете, он должен отслеживать, где он был в коллекции и что будет дальше.источник
Iterable
расширяетсяTraversable
, так что я думаю, вы имеете в видуTraversable
s, которые неIterable
s.Traversable
интерфейса не требует сохранения состояния, в то время как соблюдениеIterator
интерфейса требует.Traversable
s, которыеIterable
не сохраняют состояние итерации. ЭтоIterator
созданный и возвращенный объект,Iterable
который сохраняет состояние.Думайте об этом как о разнице между дутьем и сосанием.
Когда вы вызываете
Traversable
sforeach
или его производные методы, он будет передавать свои значения в вашу функцию по одному, поэтому он имеет контроль над итерацией.С
Iterator
возвращениемIterable
мысли вы высасываете из него значения, контролируя, когда переходить к следующему.источник
tl; dr
Iterables
,Traversables
которые могут создаватьIterators
Во-первых, знайте, что
Iterable
это вычитаниеTraversable
.Во-вторых,
Traversable
требует реализацииforeach
метода, который используется всем остальным.Iterable
требует реализацииiterator
метода, который используется всем остальным.Например, реализация
find
forTraversable
используетforeach
(через for понимание) и выдаетBreakControl
исключение, чтобы остановить итерацию, как только будет найден удовлетворительный элемент.Напротив,
Iterable
вычитание переопределяет эту реализацию и вызываетfind
методIterator
, который просто прекращает повторение после того, как элемент найден:Было бы неплохо не генерировать исключения для
Traversable
итерации, но это единственный способ частичной итерации при использовании толькоforeach
.С одной стороны,
Iterable
это более требовательная / мощная черта, поскольку вы можете легко реализоватьforeach
usingiterator
, но не можете реализоватьiterator
usingforeach
.Таким образом,
Iterable
предоставляет способ приостановить, возобновить или остановить итерацию с помощью состоянияIterator
. С участиемTraversable
этом все или ничего (без исключений для управления потоком).В большинстве случаев это не имеет значения, и вам понадобится более общий интерфейс. Но если вам когда-нибудь понадобится более индивидуальный контроль над итерацией, вам понадобится файл
Iterator
, который можно получить из файлаIterable
.источник
Ответ Даниэля звучит хорошо. Дайте мне посмотреть, смогу ли я выразить это своими словами.
Таким образом, Iterable может предоставить вам итератор, который позволяет вам перемещаться по элементам по одному (используя next ()), а также останавливаться и идти в любое время. Для этого итератору необходимо сохранить внутренний «указатель» на позицию элемента. Но Traversable дает вам метод foreach для одновременного обхода всех элементов без остановки.
Что-то вроде Range (1, 10) должно иметь только 2 целых числа в качестве состояния Traversable. Но Range (1, 10) как Iterable дает вам итератор, который должен использовать 3 целых числа для состояния, одно из которых является индексом.
Учитывая, что Traversable также предлагает foldLeft, foldRight, его foreach должен перемещаться по элементам в известном и фиксированном порядке. Следовательно, можно реализовать итератор для Traversable. Например, def iterator = toList.iterator
источник