Przyjrzałem się temu pytaniu, ale nadal nie rozumiem różnicy między cechami iterowalnymi i przemiennymi. Czy ktoś może wyjaśnić?
scala
scala-collections
Rahul
źródło
źródło
Traversable
w Scali 2.13 (jest nadal przechowywany jako przestarzały aliasIterable
do 2.14)Odpowiedzi:
Mówiąc prościej, iteratory zachowują stan, a trawersable nie.
Traversable
Ma jeden abstrakcyjny sposób:foreach
. Kiedy wywołaszforeach
, kolekcja dostarczy przekazanej funkcji wszystkie elementy, które przechowuje, jeden po drugim.Z drugiej strony
Iterable
metoda ma as abstrakcyjnąiterator
, która zwracaIterator
. Możesz wezwaćnext
a,Iterator
aby uzyskać następny element w wybranym przez siebie momencie. Dopóki tego nie zrobisz, musi śledzić, gdzie był w kolekcji i co dalej.źródło
Iterable
rozciąga sięTraversable
, więc myślę, że masz na myśli,Traversable
że nie sąIterable
.Traversable
interfejsem nie wymaga utrzymywania stanu, podczas gdy zgodność zIterator
interfejsem wymaga.Traversable
te, które sąIterable
, nie zachowują żadnego stanu iteracji. ToIterator
stworzone i zwrócone przez to,Iterable
co utrzymuje stan.Potraktuj to jako różnicę między dmuchaniem a ssaniem.
Kiedy wywołasz a
Traversable
sforeach
lub metody pochodne, będzie on wysyłał wartości do Twojej funkcji pojedynczo - dzięki czemu będzie miał kontrolę nad iteracją.Z
Iterator
powrotem przezIterable
jednak wysysasz z niego wartości, kontrolując, kiedy samemu przejść do następnej.źródło
tl; dr
Iterables
są,Traversables
które mogą generować stanoweIterators
Po pierwsze, wiedz, że
Iterable
to jest cechaTraversable
.Druga,
Traversable
wymaga implementacjiforeach
metody, która jest używana przez wszystko inne.Iterable
wymaga implementacjiiterator
metody, która jest używana przez wszystko inne.Na przykład implementacja
find
forTraversable
useforeach
(za pomocą a for compearing) i zgłaszaBreakControl
wyjątek, aby zatrzymać iterację po znalezieniu zadowalającego elementu.W przeciwieństwie do tego,
Iterable
odejmowania nadpisuje to wdrożenie i rozmówfind
w sprawieIterator
, która po prostu przestaje iteracji po znalezieniu element:Byłoby miło nie rzucać wyjątków dla
Traversable
iteracji, ale to jedyny sposób na częściowe iterowanie, gdy używasz justforeach
.Z jednej perspektywy
Iterable
jest bardziej wymagającą / potężną cechą, ponieważ można ją łatwo wdrożyćforeach
za pomocąiterator
, ale tak naprawdę nie można zaimplementowaćiterator
za pomocąforeach
.Podsumowując,
Iterable
zapewnia sposób na wstrzymanie, wznowienie lub zatrzymanie iteracji za pomocą stanuIterator
. ZTraversable
, to wszystko albo nic (bez wyjątków kontroli przepływu).W większości przypadków nie ma to znaczenia, a będziesz chciał mieć bardziej ogólny interfejs. Ale jeśli kiedykolwiek będziesz potrzebować bardziej spersonalizowanej kontroli nad iteracją, będziesz potrzebować pliku
Iterator
, który możesz pobrać z plikuIterable
.źródło
Odpowiedź Daniela brzmi dobrze. Zobaczmy, czy potrafię ująć to własnymi słowami.
Tak więc Iterable może dać ci iterator, który pozwala przechodzić elementy jeden po drugim (przy użyciu next ()) i zatrzymywać się i kontynuować, jak chcesz. Aby to zrobić, iterator musi utrzymywać wewnętrzny „wskaźnik” na pozycję elementu. Ale Traversable daje ci metodę, dla każdego, do przechodzenia przez wszystkie elementy naraz bez zatrzymywania się.
Coś w rodzaju Range (1, 10) musi mieć tylko 2 liczby całkowite jako stan jako Traversable. Ale Range (1, 10) jako Iterable daje iterator, który musi użyć 3 liczb całkowitych dla stanu, z których jedna jest indeksem.
Biorąc pod uwagę, że Traversable oferuje również foldLeft, foldRight, jego foreach musi przejść przez elementy w znanej i ustalonej kolejności. Dlatego można zaimplementować iterator dla Traversable. Np. Def iterator = toList.iterator
źródło