参数列表中的类型推断与setter不起作用

时间:2012-10-19 21:41:23

标签: scala functional-programming anonymous-function type-inference

让我们想象一下范围内的以下项目:

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_=)

我已经通过创造更好的抽象来超越这个问题,但我的好奇心仍然存在。

任何人都可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:3)

让我们在第一个例子中展开你正在做的事情:

Thing.data = _

是定义匿名函数的简写,如下所示:

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

所以当你打电话

perform(Thing.data = _)

相同
perform(anon)

问题是anonperform采用类型参数T,而且您没有声明T是什么。编译器只能从传递的参数中推断出函数调用中的类型参数,而不能从函数体内推断,因此它无法在anon中推断出T应该是String

请注意,如果您致电

perform[String](Thing.data = _)

编译器没有问题,因为它现在知道T应该是什么,如果你尝试使用除字符串之外的任何类型,你将得到一个类型不匹配错误,但是错误发生在匿名函数,而不是对perform的调用。

然而,当你打电话

perform(Thing.data_=)

您正在传递明确定义为Thing.data_=的方法Box[String] => Unit,因此编译器可以推断perform的类型参数,因为它即将到来来自函数参数。