4

Scala では、yieldfor ループを使用できます。例えば:

val ints: IndexedSeq[Int] = for(i <- 1 to 10) yield i

yieldしかし、次のような while ループでは動作しないことがわかりました。

while (resultSet.next()) yield new Row(resultSet)

なぜ Scala はこのように設計されているのでしょうか?

Google と stackoverflow で検索しましたが、答えが見つかりませんでした。

4

4 に答える 4

6

while ループは Java の同等の while ループであり、「for ループ」は次の関数呼び出しに変換されるためです: <IndexedSeq>.map(yield を使用する場合) または<IndexedSeq>.foreach(結果を気にしない場合)。

Scala コードの例:

class ForVsWhileLoop {
  val dummy = for(i <- 1 to 10) yield i

  var dummy2 = Seq.empty[Int]
  var i = 0
  while(i <= 10)
    dummy2 :+= i
}

(scala -Xprint:parse ForVsWhileLoop.scala) にコンパイルします。

[[syntax trees at end of                    parser]] // ForVsWhileLoop.scala
package <empty> {
  class ForVsWhileLoop extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };

    // ***********************************************
    // the 'for loop' is translated to a function call
    val dummy = 1.to(10).map(((i) => i));


    var dummy2 = Seq.empty[Int];
    var i = 0;

    // *******************
    // classic while loop
    while$1(){
      if (i.$less$eq(10))
        {
          dummy2.$colon$plus$eq(i);
          while$1()
        }
      else
        ()
    }
  }
}
于 2014-11-23T15:19:49.697 に答える
3

違いは、DSL と見なすことができる for 内包の解釈にあります。収量がある場合、理解はmapflatMapを使用して何かに変換され、結果が収集されます。yield がない場合、式はforeachを使用して何かに変換され、結果を無視してすべての値を反復処理します。

一方、特定の条件が満たされるまで何かを実行し、何も返さない関数、つまり最後にUnitを返すだけの関数です。結果を返すためではなく、sied 効果のために呼び出されるだけです。したがって、yieldを使用しても、結果は破棄されます。

上記の実装は Iterator パターンを使用しており、foreachとまったく同じように機能します。

foreachのようにUnit返します。

scala> val res : Unit = (1 to 10) foreach {i => i + 1}

一方for with yieldは結果を返し、map のように動作します。

scala> val res : Seq[Int] = (1 to 10) map {i => i + 1}
res: Seq[Int] = Vector(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

scala> val res = for (i<- 1 to 10) yield i +1 
res: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
于 2014-11-23T15:34:46.187 に答える
1

ここで説明されているように動作するためwhile: while-loop-expressions つまり while loop expression returns Unit.

ここで説明されているようyieldに、値はこれに暗黙的に変換されます: Scala の Unit 型への暗黙的な変換Unit

于 2014-11-23T16:01:51.517 に答える