首页 文章

在Scala 2.8集合中,为什么Traversable类型添加到Iterable之上?

提问于
浏览
19

我知道要 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 回答

  • -3

    我在IRC问过David McIver这个问题 . 他说他不再记得所有的原因,但他们包括:

    • “迭代器经常很烦人......实施”

    • 迭代器“有时不安全(由于循环开始和结束时的设置/拆除)”

    • 希望通过foreach而不是通过迭代器实现一些事情来提高效率(目前的HotSpot编译器尚未实际获得增益)

  • 4

    我怀疑一个原因是,使用抽象 foreach 方法为具有抽象 iterator 方法的集合编写具体实现要容易得多 . 例如,在C#中,您可以编写 IEnumerable<T>GetEnumerator 方法的实现,就好像它是一个 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)
    }
    
  • 11

    关于你的上一个问题:

    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 中捕获并返回 .

相关问题