7

スコープ内の次の項目を想像してみましょう。

object Thing { 
  var data: Box[String] = Empty
}

def perform[T](setter: Box[T] => Unit) {
  // doesn't matter
}

以下はコンパイルに失敗します:

perform(Thing.data = _)

エラーメッセージは次のとおりです。

<console>:12: error: missing parameter type for expanded function ((x$1) => Thing.data = x$1)
              perform(Thing.data = _)
                                   ^
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error.
              perform(Thing.data = _)
                                 ^

以下がコンパイルされている間:

perform(Thing.data_=)

それ以来、より良い抽象化を作成することでこの問題を克服しましたが、私の好奇心はまだ残っています。

誰かがこれがなぜであるか説明できますか?

4

1 に答える 1

3

最初の例で行っていることを拡張してみましょう。

Thing.data = _

匿名関数を定義するための省略形で、次のようになります。

def anon[T](x: Box[T]) {
  Thing.data = x
}

だからあなたが電話するとき

perform(Thing.data = _)

それはと同じです

perform(anon)

問題はanonperform型パラメータを取得することTであり、どの時点でも何でTあるかを宣言していません。コンパイラーは、関数本体内からではなく、渡された引数からのみ関数呼び出しの型パラメーターを推測できるため、それを推測することはできanonませTString

電話をかける場合は注意してください

perform[String](Thing.data = _)

コンパイラは、何Tをすべきかを認識しているため、問題はありません。文字列以外の型を使用しようとすると、型の不一致エラーが発生しますが、エラーは、への呼び出しではなく、無名関数の本体で発生します。perform

ただし、電話するとき

perform(Thing.data_=)

Thing.data_=として明示的に定義されているメソッドを渡すBox[String] => Unitので、コンパイラは関数の引数から取得されているため、の型パラメータを推測できます。perform

于 2012-10-19T22:46:49.760 に答える