14

誰かがここで何が起こっているのか正確に説明できますか? 私は今それを完全に理解していません:

val s = Seq(1D,2D,3D,4D)
case class WithUnit(value: Double, unit: String)
s map { WithUnit(_,"cm") } // works
s map { WithUnit(value = _ , unit = "cm") } // error: missing parameter type for expanded function ((x$2) => value = x$2)

引数の名前を書いたので、コンパイラはパラメータの型を推測できないと思います。しかし、なぜですか?引数の名前を言うだけで、もっと難しくないはず?!

ありがとう!

4

2 に答える 2

30

あなたが書いたとき:

 WithUnit(value = _, unit = "cm")

あなたはそれを意味したかった:

 x => WithUnit(value = x, unit = "cm")

しかし、エラー メッセージをよく見ると、コンパイラはそれをそのように認識せず、次のように解析したことがわかります。

 WithUnit(x => value = x, unit = "cm"})

ご覧のとおり、_ は必要以上にスコープが狭くなっています。

_ は常に、可能な限り最も縮退していないスコープを選択します。スコープは、型に関係なく、構文解析中に純粋に構文的に決定されます。

非縮退とは、コンパイラがあなたの意図を理解していなかったことを意味します。

WithUnit(value = x => x, unit = "cm")

最も厳密な非縮退スコープとは、アンダースコアに関連する最も内側の関数括弧によって定義されるスコープを意味します。このような規則がないと、コンパイラは、関数呼び出しがネストされているときに、どの _ がどの関数に対応するかを知ることができません。

于 2011-03-10T13:00:44.727 に答える
3

これを試して:

scala> val withUnits = s map { x => WithUnit(value = x, unit = "cm") }
withUnits: Seq[WithUnit] = List(WithUnit(1.0,cm), WithUnit(2.0,cm), WithUnit(3.0,cm), WithUnit(4.0,cm))

問題は、アンダースコアを使用して任意の関数を直接定義することです。

詳細な説明は8.5 章にあります。"Programming in Scala" book のプレースホルダー構文

于 2011-03-10T12:25:52.607 に答える