Rah*_*hul 95 scala scala-collections
我已经看过这个问题,但仍然不理解Iterable和Traversable特征之间的区别.谁能解释一下?
Dun*_*gor 221
把它想象成吹和吸吮之间的区别.
当你调用一个Traversables foreach或它的派生方法时,它会一次一个地将它的值放入你的函数中 - 所以它可以控制迭代.
通过a Iterator返回Iterable,你可以从中取出值,控制何时自己移动到下一个值.
Dan*_*ral 118
简而言之,迭代器保持状态,遍历不会.
A Traversable有一个抽象方法:foreach.当你调用时foreach,集合将一个接一个地传递它保存的所有元素.
另一方面,有一个Iterable抽象方法iterator,它返回一个Iterator.您可以在选择时调用nexta Iterator来获取下一个元素.在你做之前,它必须跟踪它在集合中的位置,以及接下来的内容.
Pau*_*per 21
tl; dr Iterables是Traversables可以产生有状态的Iterators
首先,要知道这Iterable是次要的Traversable.
第二,
Traversable需要实现其他所有foreach方法使用的方法.
Iterable需要实现其他所有iterator方法使用的方法.
例如,findfor的Traversable使用实现foreach(通过for comprehension)并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
}
}
Run Code Online (Sandbox Code Playgroud)
相比之下,Iterable减覆盖这个实现,并呼吁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
}
}
Run Code Online (Sandbox Code Playgroud)
不要为Traversable迭代抛出异常会很好,但这是使用just时部分迭代的唯一方法foreach.
从一个角度来看,Iterable是更苛刻/更强大的特性,因为你可以轻松实现foreach使用iterator,但你无法真正实现iterator使用foreach.
总之,Iterable提供了一种通过有状态暂停,恢复或停止迭代的方法Iterator.随着Traversable,它是全部或全部(没有流量控制的例外).
大多数时候它并不重要,你会想要更通用的界面.但是如果你需要更多的自定义控制迭代,你需要一个Iterator,你可以从一个Iterable.