理解のためのscala“ < - ”
-
04-10-2019 - |
質問
Scalaには常に「自然な説明」があることがわかりました。常に「ああ、それは単なる関数であり、これとそのオブジェクトとそのパラメーターに単なる関数です」。ある意味では、他の言語から知っているので、本当にコンパイラマジックはありません。
私の質問は次のとおりです <- 次のコードで使用されるオペレーター:
for(i <- 0 to 10) println(i)
この例では、次のようなものに書き直されているのがわかります。
0.to(10).foreach((i:Int)=>println(i))
しかし、これはどのように説明していません 私 foreach関数内の匿名関数に運ばれました。あなたが書く時点で 私 それはオブジェクトではなく、まだ宣言された変数ではありません。それで、それは何ですか、そしてそれはどのようにforeachの内側に引き継がれているのでしょうか?
私の推測では、私はついに実際に何かを発見しました コンパイラマジック
御時間ありがとうございます。
明確にするために、 私の質問は、私はそれを関数と呼ぶことができるオブジェクトではないので、< - オペレーターはコードの1行目でどのように機能するかです。
解決
<-
言語定義のキーワードシンボルです =>
しかし、はっきりとは対照的です ->
(これは定義されたシンボルです)。基本的なScala文法の一部であるため、バインディングを作成するために使用できます( i
あなたの例では、これはユーザー定義の構成要素ではできないものです。
他のヒント
デイブの答えを増やすために、Scala Language Specificationの「補完」の「補完」の翻訳スキーマが次のとおりです。
理解
for (enums) yield e
式を評価しますe
列挙者の列挙によって生成された各バインディングについて。列挙者のシーケンスは、常にジェネレーターから始まります。これに続いて、さらに発電機、値の定義、またはガードが続くことができます。ジェネレーター
p <- e
式からバインディングを生成しますe
何らかの形でパターンに対して一致しますp
. 。値定義val p = e
値名をバインドしますp
(またはパターン内のいくつかの名前p
)式を評価した結果e
. 。警備員if e
列挙されたバインディングを制限するブール式が含まれています。ジェネレーターとガードの正確な意味は、4つの方法の呼び出しへの翻訳によって定義されます。
map
,filter
,flatMap
, 、 とforeach
. 。これらの方法は、さまざまなキャリアタイプに対してさまざまな方法で実装できます。翻訳スキームは次のとおりです。最初のステップでは、すべてのジェネレーター
p <- e
, 、Pが反論できない(§8.1)。e
に置き換えられますp <- e.filter { case p => true; case _ => false }
次に、すべての包含が排除されるまで、次のルールが繰り返し適用されます。
理解のため
for (p <- e) yield e0
に翻訳されていますe.map { case p => e0 }
.理解のため
for (p <- e) e0
に翻訳されていますe.foreach { case p => e0 }
.理解のため
for (p <- e; p0 <- e0 . . .) yield e00
, 、 どこ 。 。 。発電機またはガードの(おそらく空の)シーケンスは次のとおりです。e.flatMap { case p => for (p0 <- e0 . . .) yield e00 }
.理解のため
for (p <- e; p0 <- e0 . . .) e00
どこ 。 。 。発電機またはガードの(おそらく空の)シーケンスは次のとおりです。e.foreach { case p => for (p0 <- e0 . . .) e00 }
.ジェネレーター
p <- e
ガードが続きますif g
単一のジェネレーターに翻訳されています:
p <- e.filter((x1, . . . , xn) => g )
どこx1
, . . . ,xn
の自由変数ですp
.ジェネレーター
p <- e
その後、値定義が続きますval p0 = e0
値のペアの次のジェネレーターに翻訳されています。x
とx0
新鮮な名前です:val (p, p0) <- for(x@p <- e) yield { val x0@p0 = e0; (x, x0) }
この場合、それは本当にちょっとしたコンパイラマジックです。理解のための翻訳からフィルター/マップ/フラットマップ形式への翻訳は、更新および適用方法の特別な形式の変換によく似た特別なデスガーリングです。