让我们想象一下范围内的以下项目:
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_=)
我已经通过创造更好的抽象来超越这个问题,但我的好奇心仍然存在。
任何人都可以解释为什么会这样吗?
答案 0 :(得分:3)
让我们在第一个例子中展开你正在做的事情:
Thing.data = _
是定义匿名函数的简写,如下所示:
def anon[T](x: Box[T]) {
Thing.data = x
}
所以当你打电话
perform(Thing.data = _)
与
相同perform(anon)
问题是anon
和perform
采用类型参数T
,而且您没有声明T
是什么。编译器只能从传递的参数中推断出函数调用中的类型参数,而不能从函数体内推断,因此它无法在anon
中推断出T
应该是String
。
请注意,如果您致电
perform[String](Thing.data = _)
编译器没有问题,因为它现在知道T
应该是什么,如果你尝试使用除字符串之外的任何类型,你将得到一个类型不匹配错误,但是错误发生在匿名函数,而不是对perform
的调用。
然而,当你打电话
perform(Thing.data_=)
您正在传递明确定义为Thing.data_=
的方法Box[String] => Unit
,因此编译器可以推断perform
的类型参数,因为它即将到来来自函数参数。