我知道要 Traversable
,你只需要一个 foreach
方法 . Iterable
需要 iterator
方法 .
Scala 2.8集合SID和"Fighting Bitrot with Types"论文基本上都没有提到为什么添加了 Traversable
. SID只说"David McIver... proposed Traversable as a generalization of Iterable."
我从IRC的讨论中模糊地收集到,当收集的遍历终止时,它与回收资源有关吗?
以下可能与我的问题有关 . TraversableLike.scala
中有一些奇怪的函数定义,例如:
def isEmpty: Boolean = {
var result = true
breakable {
for (x <- this) {
result = false
break
}
}
result
}
我认为有一个很好的理由不仅仅是写成:
def isEmpty: Boolean = {
for (x <- this)
return false
true
}
3 回答
我在IRC问过David McIver这个问题 . 他说他不再记得所有的原因,但他们包括:
“迭代器经常很烦人......实施”
迭代器“有时不安全(由于循环开始和结束时的设置/拆除)”
希望通过foreach而不是通过迭代器实现一些事情来提高效率(目前的HotSpot编译器尚未实际获得增益)
我怀疑一个原因是,使用抽象
foreach
方法为具有抽象iterator
方法的集合编写具体实现要容易得多 . 例如,在C#中,您可以编写IEnumerable<T>
的GetEnumerator
方法的实现,就好像它是一个foreach
方法:(编译器生成一个适当的状态机来驱动迭代通过
IEnumerator
. )在Scala中,你必须编写自己的Iterator[T]
实现来执行此操作 . 对于Traversable
,您可以执行与上述实现相同的操作:关于你的上一个问题:
这大致由编译器翻译为:
所以你根本无法摆脱foreach,isEmpty总是会返回true .
这就是"hacky" Breakable的构造,它通过抛出一个Control-Exception来打破foreach,在
breakable
中捕获并返回 .