匿名函式(也稱為 lambda)是一段程式碼區塊,傳遞為高階函式的引數。維基百科將 匿名函式 定義為「未繫結至識別碼的函式定義」。
例如,假設有一個像這樣的清單
val ints = List(1, 2, 3)
您可以使用 List
類別的 map
方法和自訂匿名函式,透過將 ints
中的每個元素加倍,建立一個新的清單
val doubledInts = ints.map(_ * 2) // List(2, 4, 6)
正如註解所示,doubledInts
包含清單 List(2, 4, 6)
。在該範例中,程式碼的這個部分是一個匿名函式
_ * 2
這是一種簡寫方式,表示「將給定的元素乘以 2」。
較長的格式
當您熟悉 Scala 之後,您將始終使用該格式在函式中的一個位置使用一個變數來撰寫匿名函式。但是,如果您願意,您也可以使用較長的格式來撰寫它們,因此除了撰寫這段程式碼之外
val doubledInts = ints.map(_ * 2)
您也可以使用這些格式來撰寫
val doubledInts = ints.map((i: Int) => i * 2)
val doubledInts = ints.map((i) => i * 2)
val doubledInts = ints.map(i => i * 2)
所有這些程式碼行具有完全相同的含義:將 ints
中的每個元素加倍,以建立一個新的清單 doubledInts
。(每種格式的語法將在稍後說明。)
如果您熟悉 Java,那麼了解這些 map
範例等同於以下 Java 程式碼可能會有所幫助
List<Integer> ints = List.of(1, 2, 3);
List<Integer> doubledInts = ints.stream()
.map(i -> i * 2)
.collect(Collectors.toList());
縮短匿名函式
當您想要明確表示時,可以使用此長格式撰寫匿名函式
val doubledInts = ints.map((i: Int) => i * 2)
該表達式中的匿名函式如下
(i: Int) => i * 2
如果您不熟悉此語法,可以將 =>
符號視為轉換器,因為表達式會轉換符號左側的參數清單(名為 i
的 Int
變數),並使用 =>
符號右側的演算法(在本例中,為將 Int
加倍的表達式)產生新的結果。
縮短該表達式
此長格式可以縮短,如下列步驟所示。首先,再次說明最長且最明確的格式
val doubledInts = ints.map((i: Int) => i * 2)
由於 Scala 編譯器可以從 ints
中的資料推斷出 i
是 Int
,因此可以移除 Int
宣告
val doubledInts = ints.map((i) => i * 2)
由於只有一個參數,因此不需要參數 i
周圍的括號
val doubledInts = ints.map(i => i * 2)
由於 Scala 允許您使用 _
符號代替變數名稱(當參數只在函式中出現一次時),因此可以進一步簡化程式碼
val doubledInts = ints.map(_ * 2)
進一步縮短
在其他範例中,您可以進一步簡化匿名函式。例如,從最明確的格式開始,您可以使用 List
類別 foreach
方法,使用此匿名函式列印 ints
中的每個元素
ints.foreach((i: Int) => println(i))
與之前相同,不需要 Int
宣告,而且由於只有一個參數,因此不需要 i
周圍的括號
ints.foreach(i => println(i))
由於 i
只在函式主體中使用一次,因此可以使用 _
符號進一步簡化表達式
ints.foreach(println(_))
最後,如果匿名函式包含一個方法呼叫,且該方法呼叫只有一個參數,則不需要明確命名和指定參數,因此您最後只需要撰寫方法名稱(在此為 println
)
ints.foreach(println)