Scala:Scala 集合中的 Traversable 和 Iterable trait 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7425370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala: What is the difference between Traversable and Iterable traits in Scala collections?
提问by Rahul
I have looked at this questionbut still don't understand the difference between Iterable and Traversable traits. Can someone explain ?
我看过这个问题,但仍然不明白 Iterable 和 Traversable 特征之间的区别。有人可以解释一下吗?
回答by Duncan McGregor
Think of it as the difference between blowing and sucking.
把它想象成吹和吸的区别。
When you have call a Traversables foreach, or its derived methods, it will blow its values into your function one at a time - so it has control over the iteration.
当您调用 a Traversablesforeach或其派生方法时,它将一次将其值吹入您的函数中 - 因此它可以控制迭代。
With the Iteratorreturned by an Iterablethough, you suck the values out of it, controlling when to move to the next one yourself.
通过 aIterator返回Iterable的值,您可以从中吸取值,自己控制何时移动到下一个值。
回答by Daniel C. Sobral
To put it simply, iterators keep state, traversables don't.
简而言之,迭代器保持状态,而遍历器则不。
A Traversablehas one abstract method: foreach. When you call foreach, the collectionwill feed the passed function all the elements it keeps, one after the other.
ATraversable有一个抽象方法:foreach. 当您调用 时foreach,集合将一个接一个地为传递的函数提供它保留的所有元素。
On the other hand, an Iterablehas as abstract method iterator, which returns an Iterator. You can call nexton an Iteratorto get the next element at the time of your choosing. Until you do, it has to keep track of where it was in the collection, and what's next.
另一方面, anIterable具有抽象方法iterator,它返回一个Iterator。您可以next在Iterator您选择的时间调用an来获取下一个元素。在你这样做之前,它必须跟踪它在集合中的位置,以及下一步是什么。
回答by Paul Draper
tl;drIterablesare Traversablesthat can produce stateful Iterators
tl;drIterables是Traversables可以产生有状态的Iterators
First, know that Iterableis subtrait of Traversable.
首先,知道这Iterable是 的子特征Traversable。
Second,
第二,
Traversablerequires implementing theforeachmethod, which is used by everything else.Iterablerequires implementing theiteratormethod, which is used by everything else.
Traversable需要实现该foreach方法,其他所有东西都使用该方法。Iterable需要实现该iterator方法,其他所有东西都使用该方法。
For example, the implemetation of findfor Traversableuses foreach(via a for comprehension) and throws a BreakControlexception to halt iteration once a satisfactory element has been found.
例如,实现findforTraversable使用foreach(通过 for 理解)并BreakControl在找到令人满意的元素后抛出异常以停止迭代。
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
}
}
In contrast, the Iterablesubtract overrides this implementation and calls findon the Iterator, which simply stops iterating once the element is found:
相比之下,Iterablesubtract 覆盖了这个实现并调用find了Iterator,一旦找到元素,它就会停止迭代:
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
}
}
It'd be nice not to throw exceptions for Traversableiteration, but that's the only way to partially iterate when using just foreach.
最好不要为Traversable迭代抛出异常,但这是在使用 just 时部分迭代的唯一方法foreach。
From one perspective, Iterableis the more demanding/powerful trait, as you can easily implement foreachusing iterator, but you can't really implement iteratorusing foreach.
从一个角度来看,Iterable是更苛刻/更强大的特性,因为您可以轻松实现foreachusing iterator,但您不能真正实现iteratorusing foreach。
In summary, Iterableprovides a way to pause, resume, or stop iteration via a stateful Iterator. With Traversable, it's all or nothing (sans exceptions for flow control).
总之,Iterable提供了一种通过 stateful 暂停、恢复或停止迭代的方法Iterator。使用Traversable,要么全有要么全无(流量控制没有例外)。
Most of the time it doesn't matter, and you'll want the more general interface. But if you ever need more customized control over iteration, you'll need an Iterator, which you can retrieve from an Iterable.
大多数时候这并不重要,您会想要更通用的界面。但是,如果您需要对迭代进行更多自定义控制,则需要一个Iterator,您可以从Iterable.
回答by user11595225
Daniel's answer sounds good. Let me see if I can to put it in my own words.
丹尼尔的回答听起来不错。让我看看我是否可以用我自己的话来表达。
So an Iterable can give you an iterator, that lets you traverse the elements one at a time (using next()), and stop and go as you please. To do that the iterator needs to keep an internal "pointer" to the element's position. But a Traversable gives you the method, foreach, to traverse all elements at once without stopping.
所以 Iterable 可以给你一个迭代器,它让你一次遍历一个元素(使用 next()),并随心所欲地走走停停。为此,迭代器需要保留一个指向元素位置的内部“指针”。但是 Traversable 为您提供了 foreach 方法,可以一次不停止地遍历所有元素。
Something like Range(1, 10) needs to have only 2 integers as state as a Traversable. But Range(1, 10) as an Iterable gives you an iterator which needs to use 3 integers for state, one of which is an index.
像 Range(1, 10) 这样的东西只需要 2 个整数作为 Traversable 的状态。但是 Range(1, 10) 作为 Iterable 为您提供了一个迭代器,它需要使用 3 个整数作为状态,其中一个是索引。
Considering that Traversable also offers foldLeft, foldRight, its foreach needs to traverse the elements in a known and fixed order. Therefore it's possible to implement an iterator for a Traversable. E.g. def iterator = toList.iterator
考虑到Traversable还提供了foldLeft、foldRight,它的foreach需要按照已知的固定顺序遍历元素。因此,可以为 Traversable 实现迭代器。例如 def iterator = toList.iterator

