在参数列表中输入推理结合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)

问题是anonperform一个类型参数T并且你没有声明T是什么。 编译器只能从传递的参数推断出一个函数调用类型参数,而不是从函数体中,因此它不能推断anonT应该是String

注意,如果你打电话

perform[String](Thing.data = _)

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

但是,当你打电话

perform(Thing.data_=)

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

链接地址: http://www.djcxy.com/p/11339.html

上一篇: type inference in argument list in combination with setter not working

下一篇: Why can't pip find packages listed in `pip search` results?