鉴于此定义:
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)
我觉得这很简洁.我真的不介意这样做,虽然它使方法重载更难.但是,我想了解为什么第二种变体可行而第一种不起作用?
第二种变体是有效的,因为Scala通过参数块改进了它的类型参数块.如果未指定函数的输入参数类型,则可能会更改T基于第一个参数推断的类型.如果将其推送到单独的参数块,Scala已经确定了它到达该块时T必须达到的值,因此它填充了函数参数类型的唯一可能值.