4

次のケースでパターンマッチングがどのように機能するかを誰かが知っているかどうかを知りたくて、好奇心からこの質問を投稿しています。次のように定義された関数値があるとします。

val f = (s: String) => s.toInt

その型はもちろん String => Int です。ここで、この関数に渡されたものの出力に一致するパターンに基づいて、新しい関数を作成したいと考えています。次のように定義できます。

val f2 = f(_: String) match {
  case i: Int => i + 2
}

今、私の新しい関数も String => Int からのものですが、プロセス中に 2 が追加されます。次のように呼び出すことができます。

scala> f2("3")
res0: Int = 5

部分的な適用を行わずに同じことを行うと、関数自体に基づいて一致が得られます。

val f3 = f match {
  case x => "matched: " + x
}

ここで、値 f3 には「matched <function1>」が割り当てられます。これは、値として 'f' を使用して match を呼び出したためです。

私の質問はこれです.Scalaはこれら2つをどのように区別しますか? どちらも関数値であり、どちらも String => Int 型です。実際、match を実行する前に部分的に適用された関数値を一時変数 tmp に割り当てると、f3 と同じように動作します。

val tmp = f(_: String)
val f4 = tmp match {
  case x => "matched: " + x
}

f4 には、関数 String => Int ではなく、"matched <function1>" が割り当てられます。

どちらかをやりたいという価値はわかりますが、それがどのように行われるのかに興味があります。これは、マッチのコンテキストで関数を部分的に適用していることをどういうわけか理解して、何か違うものを生成する魔法の Scala が追加されたものですか...

4

1 に答える 1

9

それがアンダースコアの仕組みです。

f(_: String) match {
  case i: Int => i + 2
}

の省略形です

(x: String) => (f(x) match {
  case i: Int => i + 2
})

(物事をより明確にするために括弧が追加されています)が、他の例は次と同等です

(x: String => f(x)) match {
  case y => "matched: " + y
}
于 2012-06-20T06:02:08.870 に答える