我看了this question但仍然不理解Iterable和Traversable特征之间的区别 . 谁能解释一下?
简而言之,迭代器保持状态,遍历不会 .
Traversable 有一个抽象方法: foreach . 当你调用 foreach 时,该集合将为它传递的所有元素提供一个接一个的传递函数 .
Traversable
foreach
另一方面, Iterable 具有抽象方法 iterator ,它返回 Iterator . 您可以在 Iterator 上调用 next 以在您选择时获取下一个元素 . 在你做之前,它必须跟踪它在集合中的位置,以及下一步 .
Iterable
iterator
Iterator
next
把它想象成吹气和吸吮之间的区别 .
当您调用 Traversable s foreach 或其派生方法时,它会一次将其值放入您的函数中 - 因此它可以控制迭代 .
使用 Iterable 返回的 Iterator ,你可以从中取出值,控制何时自己移动到下一个值 .
tl;dr Iterables 是 Traversables ,可以产生有状态的 Iterators
Iterables
Traversables
Iterators
首先,要知道 Iterable 是 Traversable 的子索引 .
第二,
Traversable 需要实现 foreach 方法,其他所有方法都使用该方法 .
Iterable 需要实现 iterator 方法,其他所有方法都使用该方法 .
例如,对于 Traversable find 的实现使用 foreach (通过for comprehension)并且一旦找到满意的元素就抛出 BreakControl 异常以停止迭代 .
find
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 } }
相比之下, Iterable subtract会覆盖此实现,并在 Iterator 上调用 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 迭代抛出异常会很好,但这是仅使用 foreach 时部分迭代的唯一方法 .
从一个角度来看, Iterable 是更苛刻/更强大的特性,因为你可以使用 iterator 轻松实现 foreach ,但你无法使用 foreach 真正实现 iterator .
总之, Iterable 提供了一种通过有状态 Iterator 暂停,恢复或停止迭代的方法 . 使用 Traversable ,它是全部或全部(没有流控制的例外) .
大多数情况下,它不需要更通用的界面 . 但是如果你需要更多的自定义控制迭代,你需要 Iterator ,你可以从 Iterable 检索 .
3 回答
简而言之,迭代器保持状态,遍历不会 .
Traversable
有一个抽象方法:foreach
. 当你调用foreach
时,该集合将为它传递的所有元素提供一个接一个的传递函数 .另一方面,
Iterable
具有抽象方法iterator
,它返回Iterator
. 您可以在Iterator
上调用next
以在您选择时获取下一个元素 . 在你做之前,它必须跟踪它在集合中的位置,以及下一步 .把它想象成吹气和吸吮之间的区别 .
当您调用
Traversable
sforeach
或其派生方法时,它会一次将其值放入您的函数中 - 因此它可以控制迭代 .使用
Iterable
返回的Iterator
,你可以从中取出值,控制何时自己移动到下一个值 .tl;dr
Iterables
是Traversables
,可以产生有状态的Iterators
首先,要知道
Iterable
是Traversable
的子索引 .第二,
Traversable
需要实现foreach
方法,其他所有方法都使用该方法 .Iterable
需要实现iterator
方法,其他所有方法都使用该方法 .例如,对于
Traversable
find
的实现使用foreach
(通过for comprehension)并且一旦找到满意的元素就抛出BreakControl
异常以停止迭代 .相比之下,
Iterable
subtract会覆盖此实现,并在Iterator
上调用find
,一旦找到该元素,它就会停止迭代:不要为
Traversable
迭代抛出异常会很好,但这是仅使用foreach
时部分迭代的唯一方法 .从一个角度来看,
Iterable
是更苛刻/更强大的特性,因为你可以使用iterator
轻松实现foreach
,但你无法使用foreach
真正实现iterator
.总之,
Iterable
提供了一种通过有状态Iterator
暂停,恢复或停止迭代的方法 . 使用Traversable
,它是全部或全部(没有流控制的例外) .大多数情况下,它不需要更通用的界面 . 但是如果你需要更多的自定义控制迭代,你需要
Iterator
,你可以从Iterable
检索 .