6

for-comprehension で val を使用すると、次の警告が表示されます。

警告: 内包表記の val キーワードは非推奨です

仕様の構文付録での生産にもかかわらず。

これは、私が次のようなことをするときに

for (x <- xs; a = x)

次のようなことをする場合など、変数を実際に導入しているわけではありません

for (x <- xs) yield { implicit val a = x; /* more */ }

ここで、いつものように、ブレースは新しいスコープを開始し、そこで新しい val または新しい Implicit を導入できます。

私は本当にそれで何をしているのaですか?

スタックスペースを消費していますか? ヒープ?別の別名?

4

1 に答える 1

7

通常のval pat = expr定義のように、等号の左側にあるものは単なるパターンです。

構文仕様の Enumerator 生成は、for-expr の句が generator (a <- b)、guardif condまたは val defになる可能性があることを示していますa = b

任意の式にできる部分はb( と の右にあるよう<-=) と条件です。

Responder.execは、条件を利用して任意のコードを実行し、自明に評価して を評価しtrueます。

つまり、条件から任意の副作用を実行できることを意味します。

// yucky, yet instructive
scala> val xs = List(1,2,3)
scala> def bar(implicit i: Int) = Some(i+1)
scala> implicit var imp: Int = 0
scala> for { a<-xs; if { imp=a; true }; b<-bar } yield b
res6: List[Int] = List(2, 3, 4)

同様に、val def desugar は次のようになります。

tmp <- xs
a = f(tmp)  // some arbitrary function of tmp
// amounts to
(tmp, a) <- for (x@tmp <- xs) yield { val x0@a=f(tmp); (x, x0) }

待って、本当に?

scala> def f(vs: List[Int]) = for (a <- vs; b = a+1) yield b
f: (vs: List[Int])List[Int]

これを行うには、最近の repl が必要です。

scala> :javap f
[snip]
  public scala.collection.immutable.List<java.lang.Object> f(scala.collection.immutable.List<java.lang.Object>);
    flags: ACC_PUBLIC

    Code:
      stack=3, locals=2, args_size=2
         0: aload_1       
         1: new           #16                 // class $anonfun$f$1
         4: dup           
         5: invokespecial #17                 // Method $anonfun$f$1."<init>":()V
         8: getstatic     #22                 // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
        11: invokevirtual #26                 // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
        14: invokeinterface #32,  3           // InterfaceMethod scala/collection/TraversableLike.map:(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
        19: checkcast     #28                 // class scala/collection/TraversableLike
        22: new           #34                 // class $anonfun$f$2
        25: dup           
        26: invokespecial #35                 // Method $anonfun$f$2."<init>":()V
        29: getstatic     #22                 // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
        32: invokevirtual #26                 // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
        35: invokeinterface #32,  3           // InterfaceMethod scala/collection/TraversableLike.map:(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
        40: checkcast     #37                 // class scala/collection/immutable/List
        43: areturn       

中間式と生成のための 2 つの map 呼び出しが表示されます。

さらに調べてみると、最初の anonfun はInt => Int(つまり、a+1) ではなく、Int => (Int,Int).

したがって、導入した val はタプルの一部として渡されるだけです。

于 2012-12-29T23:52:09.843 に答える