20

私は、あるためにはTraversable、あなたは方法を持っているだけでよいことを知っていますforeach。メソッドIterableが必要です。iterator

Scala2.8コレクションのSIDと「FightingBitrotwithTypes」の論文はどちらも基本的Traversableに追加された理由については言及していません。SIDは、「DavidMcIver...がIterableの一般化としてTraversableを提案した」とだけ述べています。

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

3 に答える 3

11

これについて IRC で David McIver に尋ねました。彼は、すべての理由を覚えていないと言いましたが、次のものが含まれていました。

  • 「イテレータはしばしば煩わしい...実装する」

  • イテレータは「安全でない場合がある (ループの開始時と終了時のセットアップ/ティアダウンが原因で)」

  • イテレータではなく foreach を介していくつかのことを実装することで効率が向上することが期待されています (現在の HotSpot コンパイラで実際に実証されているとは限りません)。

于 2010-04-16T19:58:46.287 に答える
4

理由の 1 つは、抽象メソッドを使用したコレクションforeachよりも、抽象メソッドを使用したコレクションの具体的な実装を作成する方がはるかに簡単だからだと思いiteratorます。たとえば、C# では、メソッドの実装をGetEnumeratorメソッドであるIEnumerable<T>かのように記述できます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)
}
于 2010-04-08T20:42:51.670 に答える
-3

最後の質問について:

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

これは、コンパイラによって大まかに次のように変換されます。

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

したがって、単に foreach から抜け出すことができず、isEmpty は常に true を返します。

breakableこれが、Control-Exception をスローして foreach から抜け出し、それをキャッチして返す「ハッキーな」Breakable が構築された理由です。

于 2010-06-04T14:28:42.490 に答える