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

发布于 2024-08-28 00:34:57 字数 686 浏览 8 评论 0原文

我知道要实现 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

分分钟 2024-09-04 00:34:57

我在 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)

孤云独去闲 2024-09-04 00:34:57

我怀疑一个原因是,使用抽象的 foreach 方法为集合编写具体实现比使用抽象的迭代器方法要容易得多。例如,在 C# 中,您可以将 IEnumerableGetEnumerator 方法的实现编写为 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)
}

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 abstract iterator method. For example, in C# you can write the implementation the GetEnumerator method of IEnumerable<T> as if it were a foreach method:

IEnumerator<T> GetEnumerator() 
{
    yield return t1;
    yield return t2;
    yield return t3;
}

(The compiler generates an appropriate state machine to drive the iteration through the IEnumerator.) In Scala, you would have to write your own implementation of Iterator[T] to do this. For Traversable, you can do the equivalent of the above implementation:

def foreach[U](f: A => U): Unit = {
  f(t1); f(t2); f(t3)
}
怪我太投入 2024-09-04 00:34:57

只是关于你的最后一个问题:

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

just regarding your last question:

def isEmpty: Boolean = {
  for (x <- this)
    return false
  true
}

This gets roughly translated by the compiler to:

def isEmpty: Boolean = {
  this.foreach(x => return false)
  true
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文