2012-02-13 18 views
2

鑑於這樣的定義:爲什麼我需要一個curried函數來使用短佔位符語法來傳遞函數文字?

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 = _) 

我覺得這很好,簡潔。我並不介意這樣做,儘管它會讓方法更加困難。然而,我想了解,爲什麼第二個變體起作用,而第一個變體不起作用?

回答

5

第二個變體的工作原理是因爲Scala通過參數塊細化了它的類型參數塊。如果您沒有爲函數指定輸入參數的類型,則可能會根據第一個參數更改其已推斷的類型T。如果你將它推到一個單獨的參數塊中,Scala已經決定了什麼T必須是它到達該塊的時間,所以它填充函數參數類型的唯一可能的值。

+0

啊......謝謝。這只是在我的腦海中產生了巨大的咔嗒聲。當然,這讓我立即嘗試將它稱爲'model [String](...)'並且看,當然它就是這樣的。謝謝! – 2012-02-13 21:50:29

相關問題