He mirado esta pregunta pero todavía no entiendo la diferencia entre los rasgos Iterable y Traversable. ¿Alguien puede explicarlo?
scala
scala-collections
Rahul
fuente
fuente
Traversable
en Scala 2.13 (todavía se mantiene como un alias obsoletoIterable
hasta 2.14)Respuestas:
En pocas palabras, los iteradores mantienen el estado, los transitables no.
Una
Traversable
tiene un método abstracto:foreach
. Cuando llameforeach
, la colección alimentará a la función pasada con todos los elementos que conserva, uno tras otro.Por otro lado, an
Iterable
tiene como método abstractoiterator
, que devuelve unIterator
. Puede llamarnext
a unIterator
para obtener el siguiente elemento en el momento que elija. Hasta que lo haga, debe realizar un seguimiento de dónde estaba en la colección y qué sigue.fuente
Iterable
extiendeTraversable
, así que supongo que te refieres aTraversable
s que no sonIterable
s.Traversable
interfaz no requiere mantener el estado, mientras que cumplir con laIterator
interfaz sí.Traversable
s queIterable
no mantienen ningún estado de iteración. Es loIterator
creado y devuelto por elIterable
que mantiene el estado.Piense en ello como la diferencia entre soplar y chupar.
Cuando haya llamado a
Traversable
sforeach
, o sus métodos derivados, soplará sus valores en su función uno a la vez, por lo que tiene control sobre la iteración.Con el
Iterator
devuelto por unIterable
sin embargo, succiona los valores de él, controlando cuándo pasar al siguiente usted mismo.fuente
tl; dr
Iterables
sonTraversables
que pueden producir statefulIterators
Primero, sepa que
Iterable
es un sustrato deTraversable
.Segundo,
Traversable
requiere implementar elforeach
método, que es utilizado por todo lo demás.Iterable
requiere implementar eliterator
método, que es utilizado por todo lo demás.Por ejemplo, la implementación de
find
forTraversable
usaforeach
(vía a para comprensión) y lanza unaBreakControl
excepción para detener la iteración una vez que se ha encontrado un elemento satisfactorio.Por el contrario, la
Iterable
resta anula esta implementación y llamafind
aIterator
, que simplemente deja de iterar una vez que se encuentra el elemento:Sería bueno no lanzar excepciones para la
Traversable
iteración, pero esa es la única forma de iterar parcialmente cuando se usa soloforeach
.Desde una perspectiva,
Iterable
es el rasgo más exigente / poderoso, ya que puede implementar fácilmenteforeach
usandoiterator
, pero realmente no puede implementariterator
usandoforeach
.En resumen,
Iterable
proporciona una forma de pausar, reanudar o detener la iteración mediante un statefulIterator
. ConTraversable
, es todo o nada (sin excepciones para el control de flujo).La mayoría de las veces no importa y querrá una interfaz más general. Pero si alguna vez necesita un control más personalizado sobre la iteración, necesitará un
Iterator
, que puede recuperar de unIterable
.fuente
La respuesta de Daniel suena bien. Déjame ver si puedo expresarlo con mis propias palabras.
Entonces, un Iterable puede darle un iterador, que le permite atravesar los elementos uno a la vez (usando next ()), y detenerse y avanzar cuando lo desee. Para hacer eso, el iterador necesita mantener un "puntero" interno a la posición del elemento. Pero un Traversable le brinda el método, foreach, para atravesar todos los elementos a la vez sin detenerse.
Algo como Range (1, 10) necesita tener solo 2 enteros como estado como Traversable. Pero Range (1, 10) como Iterable le brinda un iterador que necesita usar 3 enteros para el estado, uno de los cuales es un índice.
Teniendo en cuenta que Traversable también ofrece foldLeft, foldRight, su foreach necesita atravesar los elementos en un orden fijo y conocido. Por lo tanto, es posible implementar un iterador para un Traversable. Por ejemplo, def iterator = toList.iterator
fuente