@@ -13,28 +13,39 @@ layout: multipage-overview
13
13
permalink : " /zh-cn/scala3/book/:title.html"
14
14
---
15
15
16
-
17
16
匿名函数(也称为 * lambda* )是作为参数传递给高阶函数的代码块。
18
17
维基百科将 [ 匿名函数] ( https://en.wikipedia.org/wiki/Anonymous_function ) 定义为“未绑定到标识符的函数定义”。
19
18
20
19
例如,给定这样的列表:
21
20
21
+ {% tabs fun-anonymous-1 %}
22
+ {% tab 'Scala 2 and 3' %}
22
23
``` scala
23
24
val ints = List (1 , 2 , 3 )
24
25
```
26
+ {% endtab %}
27
+ {% endtabs %}
25
28
26
29
您可以通过使用 ` List ` 类 ` map ` 方法和自定义匿名函数将 ` ints ` 中的每个元素加倍来创建一个新列表:
27
30
31
+ {% tabs fun-anonymous-2 %}
32
+ {% tab 'Scala 2 and 3' %}
28
33
``` scala
29
34
val doubledInts = ints.map(_ * 2 ) // List(2, 4, 6)
30
35
```
36
+ {% endtab %}
37
+ {% endtabs %}
31
38
32
39
如注释所示,` doubledInts ` 包含列表` List(2, 4, 6) ` 。
33
40
在该示例中,这部分代码是一个匿名函数:
34
41
42
+ {% tabs fun-anonymous-3 %}
43
+ {% tab 'Scala 2 and 3' %}
35
44
``` scala
36
45
_ * 2
37
46
```
47
+ {% endtab %}
48
+ {% endtabs %}
38
49
39
50
这是“将给定元素乘以 2”的简写方式。
40
51
@@ -43,43 +54,63 @@ _ * 2
43
54
一旦你熟悉了 Scala,你就会一直使用这种形式来编写匿名函数,这些函数在函数的一个位置使用一个变量。
44
55
但如果你愿意,你也可以用更长的形式来写它们,所以除了写这段代码:
45
56
57
+ {% tabs fun-anonymous-4 %}
58
+ {% tab 'Scala 2 and 3' %}
46
59
``` scala
47
60
val doubledInts = ints.map(_ * 2 )
48
61
```
62
+ {% endtab %}
63
+ {% endtabs %}
49
64
50
65
您也可以使用以下形式编写它:
51
66
67
+ {% tabs fun-anonymous-5 %}
68
+ {% tab 'Scala 2 and 3' %}
52
69
``` scala
53
70
val doubledInts = ints.map((i : Int ) => i * 2 )
54
71
val doubledInts = ints.map((i) => i * 2 )
55
72
val doubledInts = ints.map(i => i * 2 )
56
73
```
74
+ {% endtab %}
75
+ {% endtabs %}
57
76
58
77
所有这些行的含义完全相同:将 ` ints ` 中的每个元素加倍以创建一个新列表 ` doubledInts ` 。
59
78
(稍后会解释每种形式的语法。)
60
79
61
80
如果您熟悉 Java,了解这些 ` map ` 示例与以下 Java 代码等价可能会有所帮助:
62
81
82
+ {% tabs fun-anonymous-5-b %}
83
+ {% tab 'Java' %}
63
84
``` java
64
85
List<Integer > ints = List . of(1 , 2 , 3 );
65
86
List<Integer > doubledInts = ints. stream()
66
87
.map(i - > i * 2 )
67
88
.collect(Collectors . toList());
68
89
```
90
+ {% endtab %}
91
+ {% endtabs %}
69
92
70
93
## 缩短匿名函数
71
94
72
95
当你想要明确时,你可以使用这个长格式编写一个匿名函数:
73
96
97
+ {% tabs fun-anonymous-6 %}
98
+ {% tab 'Scala 2 and 3' %}
74
99
``` scala
75
100
val doubledInts = ints.map((i : Int ) => i * 2 )
76
101
```
102
+ {% endtab %}
103
+ {% endtabs %}
77
104
78
105
该表达式中的匿名函数是这样的:
79
106
107
+ {% tabs fun-anonymous-7 %}
108
+ {% tab 'Scala 2 and 3' %}
80
109
``` scala
81
110
(i : Int ) => i * 2
82
111
```
112
+ {% endtab %}
113
+ {% endtabs %}
83
114
84
115
如果您不熟悉这种语法,将 ` => ` 符号视为转换器会有所帮助,因为表达式使用 ` => ` 符号右侧的算法(在这种情况下,一个将 ` Int ` 加倍的表达式)把符号左侧的参数列表(名为 ` i ` 的 ` Int ` 变量) * 转换* 为新结果。
85
116
@@ -88,52 +119,84 @@ val doubledInts = ints.map((i: Int) => i * 2)
88
119
这种长形式可以缩短,如以下步骤所示。
89
120
首先,这是最长和最明确的形式:
90
121
122
+ {% tabs fun-anonymous-8 %}
123
+ {% tab 'Scala 2 and 3' %}
91
124
``` scala
92
125
val doubledInts = ints.map((i : Int ) => i * 2 )
93
126
```
127
+ {% endtab %}
128
+ {% endtabs %}
94
129
95
130
因为 Scala 编译器可以从 ` ints ` 中的数据推断 ` i ` 是一个 ` Int ` ,所以可以删除 ` Int ` 声明:
96
131
132
+ {% tabs fun-anonymous-9 %}
133
+ {% tab 'Scala 2 and 3' %}
97
134
``` scala
98
135
val doubledInts = ints.map((i) => i * 2 )
99
136
```
137
+ {% endtab %}
138
+ {% endtabs %}
100
139
101
140
因为只有一个参数,所以不需要在参数 ` i ` 周围的括号:
102
141
142
+ {% tabs fun-anonymous-10 %}
143
+ {% tab 'Scala 2 and 3' %}
103
144
``` scala
104
145
val doubledInts = ints.map(i => i * 2 )
105
146
```
147
+ {% endtab %}
148
+ {% endtabs %}
106
149
107
150
因为当参数在函数中只出现一次时,Scala 允许您使用 ` _ ` 符号而不是变量名,所以代码可以进一步简化:
108
151
152
+ {% tabs fun-anonymous-11 %}
153
+ {% tab 'Scala 2 and 3' %}
109
154
``` scala
110
155
val doubledInts = ints.map(_ * 2 )
111
156
```
157
+ {% endtab %}
158
+ {% endtabs %}
112
159
113
160
### 变得更短
114
161
115
162
在其他示例中,您可以进一步简化匿名函数。
116
163
例如,从最显式的形式开始,您可以使用带有 ` List ` 类 ` foreach ` 方法的匿名函数打印 ` ints ` 中的每个元素:
117
164
165
+ {% tabs fun-anonymous-12 %}
166
+ {% tab 'Scala 2 and 3' %}
118
167
``` scala
119
168
ints.foreach((i : Int ) => println(i))
120
169
```
170
+ {% endtab %}
171
+ {% endtabs %}
121
172
122
173
和以前一样,不需要 ` Int ` 声明,因为只有一个参数,所以不需要 ` i ` 周围的括号:
123
174
175
+ {% tabs fun-anonymous-13 %}
176
+ {% tab 'Scala 2 and 3' %}
124
177
``` scala
125
178
ints.foreach(i => println(i))
126
179
```
180
+ {% endtab %}
181
+ {% endtabs %}
127
182
128
183
因为 ` i ` 在函数体中只使用一次,表达式可以进一步简化为 ` _ ` 符号:
129
184
185
+ {% tabs fun-anonymous-14 %}
186
+ {% tab 'Scala 2 and 3' %}
130
187
``` scala
131
188
ints.foreach(println(_))
132
189
```
190
+ {% endtab %}
191
+ {% endtabs %}
133
192
134
193
最后,如果一个匿名函数由一个接受单个参数的方法调用组成,您不需要显式命名和指定参数,因此您最终可以只写方法的名称(此处为 ` println ` ):
135
194
195
+ {% tabs fun-anonymous-15 %}
196
+ {% tab 'Scala 2 and 3' %}
136
197
``` scala
137
198
ints.foreach(println)
138
199
```
200
+ {% endtab %}
201
+ {% endtabs %}
139
202
0 commit comments