當你調用一個函數,你實際上調用函數的apply方法。 換句話說,考慮到本:
def doImport(fileImportID: Int, filename: String) {
println(s"Importing file #$fileImportID ($filename)")
}
下面的代碼片段:
val f = doImport _
f(123, "file.txt")
...是隻是語法糖:
val f = doImport _
f.apply(123, "file.txt")
如果有一個地方,編譯器將在使用命名參數進行調用時查找參數的名稱,這必然在apply
方法的定義中。 事實證明,在Function2
,這些參數被命名爲v1
和v2
。因此,我們可以這樣做:
scala> f.apply(v1=123, v2="file.txt")
Importing file #123 (file.txt)
現在讓我們來看看它(去除顯式調用apply
當換句話說)使用語法糖時仍然有效:
scala> f(v1=123, v2="file.txt")
Importing file #123 (file.txt)
尼斯,它的工作原理。 現在當然v1
和v2
是不太一樣的fileImportID
和filename
,但我們可以解決這個帶着幾分類型細化:
type ImportFunc = ((Int, String)=>Unit) {
def apply(fileImportID: Int, filename: String): Unit
}
基本上這只是(Int, String)=>Unit
(或者換句話說Function2[Int, String, Unit]
),但用我們想要的參數名稱重新定義apply
。 讓我們看看這個行動:
scala> val f: ImportFunc = doImport _
f: ImportFunc = <function2>
scala> f(fileImportID=123, filename="file.txt")
Importing file #123 (file.txt)
成功!
重要的一點是:在打字方面,ImportFunc
與Function2[Int, String, Unit]
相同,或與任何其他類似的改進相同。 這是因爲參數名稱不是簽名的一部分。因此,在我的示例中,f
仍然可以通過任何一個Function2[Int, String, Unit]
預計 (但從那時起,您將無法再使用自定義參數名稱來調用它)。
不喜歡爲命名目的包裝價值的案例類 – cchantep 2014-09-03 13:56:21
我將其移至另一個答案。 – skytteren 2014-09-03 14:03:10
我不知道爲什麼你將它移到另一個答案,除了可能試圖獲得更多的代表。爲什麼不把兩個選項都放在同一個選項中,因爲它們非常相似。 – kingdamian42 2014-09-03 14:20:25