为什么我需要一个curried函数才能使用短占位符语法传递函数文字?

Car*_*zel 2 scala

鉴于此定义:

class Foo(var x: String) {}

object Helper {
  def model[T](get: ? T, set: T ? Unit) : Model[T] = new Model[T] {
    override def getObject(): T = get

    override def setObject(obj: T) { set(obj) }
  }
}
Run Code Online (Sandbox Code Playgroud)

我试着model像这样打电话:

val f = new Foo("initial")
val stringModel = model(f.x, f.x = _)
Run Code Online (Sandbox Code Playgroud)

但这不起作用,编译器给了我这个,抱怨下划线:

missing parameter type for expanded function ((x$1) => f.x = x$1)
Run Code Online (Sandbox Code Playgroud)

如果我改变定义model使用两个参数列表,如下所示:

def model[T](get: ? T)(set: T ? Unit) // rest is unchanged
Run Code Online (Sandbox Code Playgroud)

然后我可以这样称呼它:

model(f.x)(f.x = _)
Run Code Online (Sandbox Code Playgroud)

我觉得这很简洁.我真的不介意这样做,虽然它使方法重载更难.但是,我想了解为什么第二种变体可行而第一种不起作用?

Rex*_*err 5

第二种变体是有效的,因为Scala通过参数块改进了它的类型参数块.如果未指定函数的输入参数类型,则可能会更改T基于第一个参数推断的类型.如果将其推送到单独的参数块,Scala已经确定了它到达该块时T必须达到的值,因此它填充了函数参数类型的唯一可能值.