J'ai regardé cette question mais je ne comprends toujours pas la différence entre les traits Iterable et Traversable. Quelqu'un peut-il expliquer?
scala
scala-collections
Rahul
la source
la source
Traversable
dans Scala 2.13 (il est toujours conservé comme alias obsolèteIterable
jusqu'à 2.14)Réponses:
Pour faire simple, les itérateurs conservent l'état, les traversables non.
A
Traversable
a une méthode abstraite:foreach
. Lorsque vous appelezforeach
, la collection alimentera la fonction passée tous les éléments qu'elle conserve, l'un après l'autre.D'autre part, an
Iterable
a comme méthode abstraiteiterator
, qui retourne unIterator
. Vous pouvez faire appelnext
à unIterator
pour obtenir l'élément suivant au moment de votre choix. Jusqu'à ce que vous le fassiez, il doit garder une trace de l'endroit où il se trouvait dans la collection et de la suite.la source
Iterable
s'étendTraversable
, donc je suppose que vous voulez direTraversable
s qui ne sont pasIterable
s.Traversable
interface ne nécessite pas de garder l'état, alors que se conformer à l'Iterator
interface le fait.Traversable
Les s quiIterable
ne conservent aucun état d'itération. C'est leIterator
créé et retourné par leIterable
qui garde l'état.Pensez-y comme la différence entre souffler et sucer.
Lorsque vous appelez un
Traversable
sforeach
, ou ses méthodes dérivées, il insuffle ses valeurs dans votre fonction une à la fois - il a donc le contrôle sur l'itération.Avec le
Iterator
retourné par unIterable
cependant, vous en aspirez les valeurs, en contrôlant vous-même le moment de passer à la suivante.la source
tl; dr
Iterables
sontTraversables
qui peuvent produire avec étatIterators
Premièrement, sachez que
Iterable
c'est un sous-portrait deTraversable
.Seconde,
Traversable
nécessite l'implémentation de laforeach
méthode, qui est utilisée par tout le reste.Iterable
nécessite l'implémentation de laiterator
méthode, qui est utilisée par tout le reste.Par exemple, l'implémentation de
find
forTraversable
usesforeach
(via un for comprehension) et lève uneBreakControl
exception pour arrêter l'itération une fois qu'un élément satisfaisant a été trouvé.En revanche, la
Iterable
soustraction remplace cette implémentation et appellefind
leIterator
, qui arrête simplement d'itérer une fois l'élément trouvé:Ce serait bien de ne pas lancer d'exceptions pour l'
Traversable
itération, mais c'est la seule façon d'itérer partiellement en utilisant justeforeach
.D'un point de vue,
Iterable
c'est le trait le plus exigeant / puissant, car vous pouvez facilement implémenter l'foreach
utilisationiterator
, mais vous ne pouvez pas vraiment implémenter l'iterator
utilisationforeach
.En résumé,
Iterable
fournit un moyen de suspendre, de reprendre ou d'arrêter l'itération via un étatIterator
. AvecTraversable
, c'est tout ou rien (sans exceptions pour le contrôle de flux).La plupart du temps, cela n'a pas d'importance et vous voudrez une interface plus générale. Mais si jamais vous avez besoin d'un contrôle plus personnalisé sur l'itération, vous aurez besoin d'un
Iterator
, que vous pouvez récupérer à partir d'un fichierIterable
.la source
La réponse de Daniel sonne bien. Voyons si je peux le dire avec mes propres mots.
Ainsi, un Iterable peut vous donner un itérateur, qui vous permet de parcourir les éléments un à la fois (en utilisant next ()), et de s'arrêter et de partir à votre guise. Pour ce faire, l'itérateur doit garder un "pointeur" interne sur la position de l'élément. Mais un Traversable vous donne la méthode, foreach, pour traverser tous les éléments à la fois sans s'arrêter.
Quelque chose comme Range (1, 10) n'a besoin que de 2 entiers comme état comme Traversable. Mais Range (1, 10) en tant que Iterable vous donne un itérateur qui doit utiliser 3 entiers pour l'état, dont l'un est un index.
Considérant que Traversable propose également foldLeft, foldRight, son foreach doit traverser les éléments dans un ordre connu et fixe. Il est donc possible d'implémenter un itérateur pour un Traversable. Par exemple, def iterator = toList.iterator
la source