In Scala 2.8 collections, why was the Traversable type added above Iterable?

筅森魡賤 提交于 2019-12-03 09:58:18

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)

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)
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!