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ć ?

Author: Community, 2011-09-15

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?

 105
Author: Daniel C. Sobral,
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.

 206
Author: Duncan McGregor,
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 IterablesTraversables, które mogą wytwarzać stanowe Iterators


Po pierwsze, wiedz, że Iterable jest podzbiorem Traversable.

Drugi,

  • Traversable wymaga implementacji metody foreach, która jest używana przez Wszystko inne.

  • Iterable wymaga implementacji metody iterator, 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.

 14
Author: Paul Draper,
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