2016-11-03 31 views
0

我對scala函數相對來說比較陌生,我對這個語法糖是如何工作的以及何時使用特定類型感到困惑。Scala:沒有參數的函數

我已經寫了3個功能都應該做同樣的事情,但我有爲什麼Function0的表現不同

版本1

val fn1 : (String) => String = System.getProperty(_) 

println(fn1("os.name")); 

版本2

val fn2 :() => String = System.getProperty("os.name") 

    println(fn2()); 
理解問題

版本2給出類型不匹配;發現:需要字符串:()⇒字符串

版本3

val fn3 =() => System.getProperty("os.name") 

println(fn3()); 

我明白,版本2階已經知道System.getProperty的返回類型,但它爲什麼產生特定的錯誤,爲什麼它阻止我明確聲明返回類型。我個人更喜歡明確的返回類型,所以我不必深入一種方法來查看它返回的內容。

回答

4

val fn2 :() => String = System.getProperty("os.name")System.getProperty("os.name")將被執行並返回一個字符串值。但是你說fn2是一個值,它是一個不帶參數並返回字符串的函數。

當你做System.getProperty(_),就像做x => System.getProperty(x),這是一個函數,它接受一個字符串並返回一個字符串。這就是第一個版本起作用的原因

+0

對不起,對於拉特如果第二個函數被解釋爲「一個值,這是一個不帶參數並返回一個字符串的函數,則對此做出響應。不會以類似的方式讀取第一個函數,即返回一個接受字符串並返回字符串的函數。相反,編譯器會發現你反對返回一個字符串而不是一個函數。 – Asrar

1

這個版本將進行類型檢查:

val fn2 :() => String =() => System.getProperty("os.name") 

調用fn2()這裏就像調用:

def fn2(): String = System.getProperty("os.name") 
fn2() 

在你fn1例如,下劃線提供這種隱含的語法,這看起來更像是你需要什麼空白的情況下:

val fn1 : (String) => (String) = (s) => System.getProperty(s) 
+0

'def's是方法,它不是一類對象,與FunctionN相反。所以'val fn2:()=> String'絕對不是'def fn2():String'。 – pedrofurla

+0

編輯我的答案爲清晰。在OP的例子中,我寫的兩個模型是等價的。 'def's不能作爲對象傳遞,但我認爲這種比較仍然有幫助。 – Tim