我知道要成为Traversable
,您只需要foreach
方法。 Iterable
需要iterator
方法。
Scala 2.8集合SID和“与类型战斗的Bitrot”论文基本上都没有提到为什么添加Traversable
。 SID只说“David McIver ......提出Traversable是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
}
答案 0 :(得分:11)
我在IRC问过David McIver这个问题。他说他不再记得所有的原因,但他们包括:
“迭代器通常很烦人......实施”
迭代器“有时不安全(由于循环开始和结束时的设置/拆除)”
希望通过foreach而不是通过迭代器实现一些功能来提高效率(目前的HotSpot编译器尚未实际获得增益)
答案 1 :(得分:4)
我怀疑一个原因是,使用抽象foreach
方法为具有抽象iterator
方法的方法编写具体实现要容易得多。例如,在C#中,您可以使用GetEnumerator
IEnumerable<T>
方法编写实现,就好像它是foreach
方法一样:
IEnumerator<T> GetEnumerator()
{
yield return t1;
yield return t2;
yield return t3;
}
(编译器生成一个适当的状态机来驱动IEnumerator
的迭代。)在Scala中,您必须编写自己的Iterator[T]
实现来执行此操作。对于Traversable
,您可以执行与上述实现相同的操作:
def foreach[U](f: A => U): Unit = {
f(t1); f(t2); f(t3)
}
答案 2 :(得分:-3)
关于你的上一个问题:
def isEmpty: Boolean = {
for (x <- this)
return false
true
}
编译器大致将其翻译为:
def isEmpty: Boolean = {
this.foreach(x => return false)
true
}
所以你根本无法摆脱foreach,isEmpty总是会返回true。
这就是为什么“hacky”Breakable的构造,它通过抛出一个Control-Exception来打破foreach,在breakable
中捕获它并返回。