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 回答