首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala2.8集合中,为什么要将Traversable类型添加到Iterable之上?

在Scala2.8集合中,为什么要将Traversable类型添加到Iterable之上?
EN

Stack Overflow用户
提问于 2010-04-09 02:16:36
回答 3查看 2.3K关注 0票数 20

我知道要成为Traversable,你只需要有一个foreach方法。Iterable需要iterator方法。

Scala2.8的集合SID和“用类型对抗Bitrot”这篇论文在为什么添加Traversable这个问题上基本上都保持沉默。SID只写着"David McIver……提议的可遍历作为迭代的泛化。“

我从IRC的讨论中模糊地了解到,当遍历集合终止时,它与回收资源有关吗?

下面的问题可能与我的问题有关。TraversableLike.scala中有一些看起来很奇怪的函数定义,例如:

代码语言:javascript
复制
def isEmpty: Boolean = {
  var result = true
  breakable {
    for (x <- this) {
      result = false
      break
    }
  }
  result
}

我假设有一个很好的理由,而不是仅仅写成:

代码语言:javascript
复制
def isEmpty: Boolean = {
  for (x <- this)
    return false
  true
}
EN

回答 3

Stack Overflow用户

发布于 2010-04-17 03:58:46

我在IRC上向David McIver询问了这个问题。他说,他不再记得所有的原因,但包括:

implement"

  • iterators有时是不安全的(由于在loop)"

  • Hoped-for开始和结束时的设置/销毁)通过
  • 而不是通过迭代器实现某些东西的效率收益(收益还不一定在当前的HotSpot编译器中实际演示)
票数 11
EN

Stack Overflow用户

发布于 2010-04-09 04:42:52

我怀疑其中一个原因是,与使用抽象的iterator方法相比,使用抽象的foreach方法为集合编写具体的实现要容易得多。例如,在C#中,您可以编写实现IEnumerable<T>GetEnumerator方法,就好像它是一个foreach方法:

代码语言:javascript
复制
IEnumerator<T> GetEnumerator() 
{
    yield return t1;
    yield return t2;
    yield return t3;
}

(编译器生成一个适当的状态机,以通过IEnumerator驱动迭代。)在Scala中,您必须编写自己的Iterator[T]实现才能做到这一点。对于Traversable,您可以执行与上述实现等效的操作:

代码语言:javascript
复制
def foreach[U](f: A => U): Unit = {
  f(t1); f(t2); f(t3)
}
票数 4
EN

Stack Overflow用户

发布于 2010-06-04 22:28:42

关于你的最后一个问题:

代码语言:javascript
复制
def isEmpty: Boolean = {
  for (x <- this)
    return false
  true
}

编译器将其粗略地翻译为:

代码语言:javascript
复制
def isEmpty: Boolean = {
  this.foreach(x => return false)
  true
}

所以你根本不能脱离foreach,isEmpty将总是返回true。

这就是为什么构造"hacky“Breakable的原因,它通过抛出一个控制异常,在breakable中捕获它并返回,从而打破了foreach。

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2602379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档