在 Scala 2.8 集合中,为什么在 Iterable 之上添加 Traversable 类型?
我知道要实现 Traversable
,您只需要一个 foreach
方法。 Iterable
需要一个iterator
方法。
Scala 2.8 集合 SID 和“Fighting Bitrot with Types”论文基本上都没有提及为什么添加 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
}
I know that to be Traversable
, you need only have a foreach
method. Iterable
requires an iterator
method.
Both the Scala 2.8 collections SID and the "Fighting Bitrot with Types" paper are basically silent on the subject of why Traversable
was added. The SID only says "David McIver... proposed Traversable as a generalization of Iterable."
I have vaguely gathered from discussions on IRC that it has to do with reclaiming resources when traversal of a collection terminates?
The following is probably related to my question. There are some odd-looking function definitions in TraversableLike.scala
, for example:
def isEmpty: Boolean = {
var result = true
breakable {
for (x <- this) {
result = false
break
}
}
result
}
I assume there's a good reason that wasn't just written as:
def isEmpty: Boolean = {
for (x <- this)
return false
true
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在 IRC 上向 David McIver 询问了此事。他说他不再记得所有的原因,但其中包括:
“迭代器通常很烦人......实现”
迭代器是“有时不安全(由于循环开始和结束时的设置/拆卸)”
希望提高效率通过 foreach 而不是通过迭代器实现某些东西的收益(收益不一定尚未通过当前的 HotSpot 编译器实际证明)
I asked David McIver about this on IRC. He said he no longer remembered all of the reasons, but they included:
"iterators are often annoying... to implement"
iterators are "sometimes unsafe (due to setup/teardown at the beginning and end of the loop)"
Hoped-for efficiency gains from implementing some things via foreach rather than via iterators (gains not necessarily yet actually demonstrated with the current HotSpot compiler)
我怀疑一个原因是,使用抽象的 foreach 方法为集合编写具体实现比使用抽象的迭代器方法要容易得多。例如,在 C# 中,您可以将
IEnumerable
的GetEnumerator
方法的实现编写为foreach
方法:(编译器生成一个适当的状态机来驱动通过
IEnumerator
的迭代。)在 Scala 中,您必须编写自己的Iterator[T]
实现来执行此操作。对于Traversable
,您可以执行与上述实现相同的操作:I suspect one reason is that it's a lot easier to write a concrete implementation for a collection with an abstract
foreach
method than for one with an abstractiterator
method. For example, in C# you can write the implementation theGetEnumerator
method ofIEnumerable<T>
as if it were aforeach
method:(The compiler generates an appropriate state machine to drive the iteration through the
IEnumerator
.) In Scala, you would have to write your own implementation ofIterator[T]
to do this. ForTraversable
, you can do the equivalent of the above implementation:只是关于你的最后一个问题:
编译器将其粗略地翻译为:
所以你根本无法突破 foreach,isEmpty 将始终返回 true。
这就是为什么构造了“hacky”Breakable,它通过抛出 Control-Exception 来突破 foreach,在
breakable
中捕获它并返回。just regarding your last question:
This gets roughly translated by the compiler to:
So you are simply not able to break out of foreach, isEmpty will always return true.
This is why "hacky" Breakable was constructed which breaks out of foreach by throwing a Control-Exception, catching it in
breakable
and returns.