2017-01-24 113 views
3

我已經找到了幾種匿名函數的語法在斯卡拉:斯卡拉匿名函數的語法和返回類型

val m5_1 = { (n: Int) => n * 5 } 

val m5_2 = (n: Int) => { n * 5 } : Int 

val m5_3: Int => Int = n => { n * 5 } 

是所有類型或更多種語法存在?

它們都是否等同?

哪一個更受歡迎?

如何在m5_1中指定返回類型?

+0

返回類型:'val m5_1:(Int)=> Int = {(n:Int)=> n * 5}'。如果你使用Intellij,它可以爲你自動添加返回類型 – nmat

回答

3

是否存在所有類型或更多的語法類型?

Lambda語法要求輸入參數類型是已知的。如果不是編譯器會引發錯誤。在所有您嘗試提供此信息的語法中。但是返回類型可以由編譯器推斷出來。

它們都是否等同?

所有等同

哪一個被更多/更少優選?

建議下面一個,如果你不希望看到明確的類型註釋

val m5_1 = { (n: Int) => n * 5 } 

我怎麼可以指定m5_1返回類型?

返回類型從lambda的最後一行推斷出來。最後一行是n * 5哪種類型的Int。因此,編譯器會爲您推薦這種類型。您可以跳過給出此類型的信息明確

5

我會嘗試添加到@ pamu的回答是:

哪一個更/更少的首選?

我想說第二個變種有點不常見。當類型推斷很容易看到的時候,你可以選擇第一種情況,否則應該如第三種情況那樣明確。你不需要花括號出現,所以一個簡單的變體是

val m5_3: Int => Int = n => n * 5 

甚至

​​

我如何指定m5_1返回類型?

返回類型爲Int => Int,所以這是同類型標註爲您在第三種情況下使用:

val m5_1: Int => Int = { (n: Int) => n * 5 } 

但隨後的過程中,你可以讓斯卡拉使用類型推斷的權利手邊:

val m5_1: Int => Int = n => n * 5 

因此這和你的第三種形式是一樣的。

請注意,第二種形式的: Int未定義m5_2的類型,即Int => Int而不是Int。它只是告訴斯卡拉n * 5的類型應該是Int。這可以幫助您閱讀代碼,但實際上並沒有改變在這種情況下推斷類型的方式。你可以認爲你是真正的第二種形式:

val m5_2 = (n: Int) => { 
    val res = n * 5: Int // : Int redundant here because it is already inferred 
    res 
} 

val res = n * 5: Int有作爲val res: Int = n * 5

0

相同的效果好了,上面的答案都正確地解釋幾乎一切我猜。我只想添加一個我們可以在這裏做的變體:

val m5_4 = {n=> n*5}:Int=>Int