Scala: Jaka jest różnica między cechami Traversable i Iterable w kolekcjach Scala?
Spojrzałem na to pytanie ale nadal nie rozumiem różnicy między cechami Iteracyjnymi i Traversable. Czy ktoś może to wyjaśnić ?
3 answers
Iteratory zachowują stan, a traversables nie.]}
A Traversable
ma jedną abstrakcyjną metodę: foreach
. Kiedy dzwonisz foreach
, zbiór będzie podawał przekazywaną funkcję wszystkim elementom, które przechowuje, jeden po drugim.
Z drugiej strony, An Iterable
MA jako metodę abstrakcyjną iterator
, która zwraca Iterator
. Możesz wywołać next
na Iterator
, aby uzyskać następny element w wybranym przez Ciebie czasie. Dopóki tego nie zrobisz, musi śledzić, gdzie był w kolekcji, a co dalej?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-15 03:10:23
Pomyśl o tym, jak o różnicy między obciąganiem a ssaniem.
Kiedy wywołasz Traversable
s foreach
, lub jej metody pochodne, będzie ona wdmuchiwać swoje wartości do twojej funkcji po kolei - więc ma kontrolę nad iteracją.
Z Iterator
zwracanym przez Iterable
, wysysasz z niego wartości, kontrolując, kiedy przejść do następnego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-16 06:22:48
Tl; dr Iterables
są Traversables
, które mogą wytwarzać stanowe Iterators
Po pierwsze, wiedz, że Iterable
jest podzbiorem Traversable
.
Drugi,
Traversable
wymaga implementacji metodyforeach
, która jest używana przez Wszystko inne.Iterable
wymaga implementacji metodyiterator
, która jest używana przez Wszystko inne.
Na przykład implementacja find
dla Traversable
używa foreach
(Poprzez a dla zrozumienia) i rzuca BreakControl
wyjątek do zatrzymania iteracji po znalezieniu zadowalającego elementu.
trait TravserableLike {
def find(p: A => Boolean): Option[A] = {
var result: Option[A] = None
breakable {
for (x <- this)
if (p(x)) { result = Some(x); break }
}
result
}
}
W przeciwieństwie do Iterable
odejmowanie nadpisuje tę implementację i wywołuje find
na Iterator
, która po prostu przestaje iterować po znalezieniu elementu:
trait Iterable {
override /*TraversableLike*/ def find(p: A => Boolean): Option[A] =
iterator.find(p)
}
trait Iterator {
def find(p: A => Boolean): Option[A] = {
var res: Option[A] = None
while (res.isEmpty && hasNext) {
val e = next()
if (p(e)) res = Some(e)
}
res
}
}
Byłoby miło nie wyrzucać wyjątków dla iteracji Traversable
, ale to jedyny sposób na częściową iterację przy użyciu just foreach
.
Z jednej perspektywy, Iterable
jest bardziej wymagającą/potężną cechą, jak można łatwo zaimplementować foreach
używając iterator
, ale tak naprawdę nie można zaimplementować iterator
używając foreach
.
W podsumowaniu, Iterable
zapewnia sposób na wstrzymanie, wznowienie lub zatrzymanie iteracji za pomocą stateful Iterator
. Z Traversable
, Wszystko albo nic (bez wyjątków dla kontroli przepływu).
Przez większość czasu to nie ma znaczenia, i będziesz chciał bardziej ogólny interfejs. Ale jeśli kiedykolwiek potrzebujesz bardziej spersonalizowanej kontroli nad iteracją, potrzebujesz Iterator
, którą możesz pobrać z Iterable
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-06 21:03:26