在参数列表中输入推理结合setter不工作
让我们想象一下范围内的以下项目:
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_=)
自那以后,我创造了一个更好的抽象,从而超越了这个问题,但我的好奇心仍然存在。
任何人都可以解释为什么这是?
让我们展开你在第一个例子中做的事情:
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
的类型参数,因为它来自函数参数。
上一篇: type inference in argument list in combination with setter not working
下一篇: Why can't pip find packages listed in `pip search` results?