Scala:Scala集合中的Traversable和Iterable特性有什么区别?

我已经看了这个问题,但仍然不明白Iterable和Traversable特性之间的区别。 有人可以解释吗?

简而言之,迭代器保持状态,可遍历不。

Traversable有一个抽象方法: foreach 。 当你调用foreach这个集合会一个接一个地传递所传递的所有元素。

另一方面, Iterable具有作为抽象方法的iterator ,它将返回一个Iterator 。 您可以在Iterator上调用next来获取您select时的下一个元素。 在你做之前,它必须跟踪collections中的位置,以及接下来的内容。

把它看作吹和吸的区别。

当你调用一个Traversableforeach或者它的派生方法时,它会一次一个地把它的值传递给你的函数,所以它可以控制迭代。

IteratorIterable返回时,你可以从中抽取值,控制何时自己移动到下一个值。

tl; dr Iterables是可Traversables ,可以产生有状态的Iterators


首先知道Iterable是可逆的。

第二,

  • Traversable需要实现foreach方法,一切都使用。

  • iterator需要实现iterator方法,其他方法都使用iterator方法。

例如,用于Traversablefind的实现使用foreach (通过for理解),并且一旦find满意的元素就会抛出一个BreakControlexception来停止迭代。

 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 } } 

相比之下, Iterable相减会覆盖这个实现,并在Iterator上调用find ,一旦find元素就停止迭代:

 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 } } 

最好不要为Traversable迭代抛出exception,但这是使用foreach时部分迭代的唯一方法。

从一个angular度来看, Iterable是更苛刻/更强大的特性,因为你可以使用iterator轻松实现foreach ,但是你不能真正使用foreach实现iterator


总之, Iterable提供了一种通过有状态Iterator暂停,恢复或停止迭代的方法。 通过Traversable ,它是全部或全部(stream量控制的例外情况)。

大多数情况下,这并不重要,您需要更一般的界面。 但是如果你需要更多的定制控制迭代,你将需要一个Iterator ,你可以从Iterable检索。