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

时间:2012-02-13 21:02:59

标签: 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) }
  }
}

我尝试像这样打电话给model

val f = new Foo("initial")
val stringModel = model(f.x, f.x = _)

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

missing parameter type for expanded function ((x$1) => f.x = x$1)

如果我将model的定义更改为使用这样的两个参数列表:

def model[T](get: ⇒ T)(set: T ⇒ Unit) // rest is unchanged

然后我可以这样称呼它:

model(f.x)(f.x = _)

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

1 个答案:

答案 0 :(得分:5)

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