Scala:Scala集合中的Traversable和Iterable特性有什么区别?
我已经看了这个问题,但仍然不明白Iterable和Traversable特性之间的区别。 有人可以解释吗?
简而言之,迭代器保持状态,可遍历不。
Traversable
有一个抽象方法: foreach
。 当你调用foreach
, 这个集合会一个接一个地传递所传递的所有元素。
另一方面, Iterable
具有作为抽象方法的iterator
,它将返回一个Iterator
。 您可以在Iterator
上调用next
来获取您select时的下一个元素。 在你做之前,它必须跟踪collections中的位置,以及接下来的内容。
把它看作吹和吸的区别。
当你调用一个Traversable
的foreach
或者它的派生方法时,它会一次一个地把它的值传递给你的函数,所以它可以控制迭代。
当Iterator
由Iterable
返回时,你可以从中抽取值,控制何时自己移动到下一个值。
tl; dr Iterables
是可Traversables
,可以产生有状态的Iterators
首先知道Iterable
是可逆的。
第二,
-
Traversable
需要实现foreach
方法,一切都使用。 -
iterator
需要实现iterator
方法,其他方法都使用iterator
方法。
例如,用于Traversable
的find
的实现使用foreach
(通过for理解),并且一旦find满意的元素就会抛出一个BreakControl
exception来停止迭代。
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
检索。