@@ -42,15 +42,21 @@ Scala 比任何其他语言都更支持 FP 和 OOP 范式的融合。
42
42
模块化的一些最佳示例可能是标准库中的类。
43
43
例如,` List ` 被定义为一个类---从技术上讲,它是一个抽象类---并且像这样创建了一个新实例:
44
44
45
+ {% tabs list %}
46
+ {% tab 'Scala 2 and 3' for=list %}
45
47
``` scala
46
48
val x = List (1 , 2 , 3 )
47
49
```
50
+ {% endtab %}
51
+ {% endtabs %}
48
52
49
53
但是,在程序员看来是一个简单的 ` List ` 实际上是由几种特殊类型的组合构建的,包括名为` Iterable ` , ` Seq ` , 和 ` LinearSeq ` 的 traits。
50
54
这些类型同样由其他小型的模块化代码单元组成。
51
55
52
56
除了从一系列模块化 traits 构建/cases像 ` List ` 这样的类型之外,` List ` API还包含数十种其他方法,其中许多是高阶函数:
53
57
58
+ {% tabs list %}
59
+ {% tab 'Scala 2 and 3' for=list-methods %}
54
60
``` scala
55
61
val xs = List (1 , 2 , 3 , 4 , 5 )
56
62
@@ -59,6 +65,8 @@ xs.filter(_ < 3) // List(1, 2)
59
65
xs.find(_ > 3 ) // Some(4)
60
66
xs.takeWhile(_ < 3 ) // List(1, 2)
61
67
```
68
+ {% endtab %}
69
+ {% endtabs %}
62
70
63
71
在这些示例中,无法修改列表中的值。
64
72
` List ` 类是不可变的,因此所有这些方法都返回新值,如每个注释中的数据所示。
@@ -68,30 +76,44 @@ xs.takeWhile(_ < 3) // List(1, 2)
68
76
Scala的 _ 类型推断_ 经常使语言感觉是动态类型的,即使它是静态类型的。
69
77
对于变量声明,情况确实如此:
70
78
79
+ {% tabs list %}
80
+ {% tab 'Scala 2 and 3' for=dynamic %}
71
81
``` scala
72
82
val a = 1
73
83
val b = " Hello, world"
74
84
val c = List (1 ,2 ,3 ,4 ,5 )
75
85
val stuff = (" fish" , 42 , 1_234.5 )
76
86
```
87
+ {% endtab %}
88
+ {% endtabs %}
77
89
78
90
当把匿名函数传递给高阶函数时,情况也是如此:
79
91
92
+ {% tabs list %}
93
+ {% tab 'Scala 2 and 3' for=dynamic-hof %}
80
94
``` scala
81
95
list.filter(_ < 4 )
82
96
list.map(_ * 2 )
83
97
list.filter(_ < 4 )
84
98
.map(_ * 2 )
85
99
```
100
+ {% endtab %}
101
+ {% endtabs %}
86
102
87
103
还有定义方法的时候:
88
104
105
+ {% tabs list %}
106
+ {% tab 'Scala 2 and 3' for=list-method %}
89
107
``` scala
90
108
def add (a : Int , b : Int ) = a + b
91
109
```
110
+ {% endtab %}
111
+ {% endtabs %}
92
112
93
113
这在Scala 3中比以往任何时候都更加真实,例如在使用[ union types] [ union-types ] 时:
94
114
115
+ {% tabs union %}
116
+ {% tab 'Scala 3 Only' for=union %}
95
117
``` scala
96
118
// union type parameter
97
119
def help (id : Username | Password ) =
@@ -103,19 +125,27 @@ def help(id: Username | Password) =
103
125
// union type value
104
126
val b : Password | Username = if (true ) name else password
105
127
```
128
+ {% endtab %}
129
+ {% endtabs %}
106
130
107
131
## 3) 简洁的语法
108
132
109
133
Scala是一种 low ceremony,“简洁但仍然可读”的语言。例如,变量声明是简洁的:
110
134
135
+ {% tabs list %}
136
+ {% tab 'Scala 2 and 3' for=concise %}
111
137
``` scala
112
138
val a = 1
113
139
val b = " Hello, world"
114
140
val c = List (1 ,2 ,3 )
115
141
```
142
+ {% endtab %}
143
+ {% endtabs %}
116
144
117
145
创建类型如traits, 类和枚举都很简洁:
118
146
147
+ {% tabs enum %}
148
+ {% tab 'Scala 3 Only' for=enum %}
119
149
``` scala
120
150
trait Tail :
121
151
def wagTail (): Unit
@@ -132,13 +162,19 @@ case class Person(
132
162
age : Int
133
163
)
134
164
```
165
+ {% endtab %}
166
+ {% endtabs %}
135
167
136
168
简洁的高阶函数:
137
169
170
+ {% tabs list-hof %}
171
+ {% tab 'Scala 2 and 3' for=list-hof %}
138
172
``` scala
139
173
list.filter(_ < 4 )
140
174
list.map(_ * 2 )
141
175
```
176
+ {% endtab %}
177
+ {% endtabs %}
142
178
143
179
所有这些表达方式以及更多表达方式都很简洁,并且仍然非常易读:我们称之为 _ 富有表现力_ 。
144
180
@@ -215,6 +251,8 @@ Scala.js 生态系统 [有几十个库](https://www.scala-js.org/libraries) 让
215
251
216
252
这里有些例子:
217
253
254
+ {% tabs list %}
255
+ {% tab 'Scala 2 and 3' for=list-more %}
218
256
``` scala
219
257
List .range(1 , 3 ) // List(1, 2)
220
258
List .range(start = 1 , end = 6 , step = 2 ) // List(1, 3, 5)
@@ -253,34 +291,50 @@ nums.sorted // List(1, 5, 7, 8, 10)
253
291
nums.sortWith(_ < _) // List(1, 5, 7, 8, 10)
254
292
nums.sortWith(_ > _) // List(10, 8, 7, 5, 1)
255
293
```
294
+ {% endtab %}
295
+ {% endtabs %}
256
296
257
297
## 8) 内置最佳实践
258
298
259
299
Scala 习语以多种方式鼓励最佳实践。
260
300
对于不可变性,我们鼓励您创建不可变的 ` val ` 声明:
261
301
302
+ {% tabs list %}
303
+ {% tab 'Scala 2 and 3' for=val %}
262
304
``` scala
263
305
val a = 1 // 不可变变量
264
306
```
307
+ {% endtab %}
308
+ {% endtabs %}
265
309
266
310
还鼓励您使用不可变集合类,例如 ` List ` 和 ` Map ` :
267
311
312
+ {% tabs list %}
313
+ {% tab 'Scala 2 and 3' for=list-map %}
268
314
``` scala
269
315
val b = List (1 ,2 ,3 ) // List 是不可变的
270
316
val c = Map (1 -> " one" ) // Map 是不可变的
271
317
```
318
+ {% endtab %}
319
+ {% endtabs %}
272
320
273
321
样例类主要用于 [ 领域建模] ({% link _ zh-cn/overviews/scala3-book/domain-modeling-intro.md %}),它们的参数是不可变的:
274
322
323
+ {% tabs list %}
324
+ {% tab 'Scala 2 and 3' for=case-class %}
275
325
``` scala
276
326
case class Person (name : String )
277
327
val p = Person (" Michael Scott" )
278
328
p.name // Michael Scott
279
329
p.name = " Joe" // 编译器错误(重新分配给 val 名称)
280
330
```
331
+ {% endtab %}
332
+ {% endtabs %}
281
333
282
334
如上一节所示,Scala 集合类支持高阶函数,您可以将方法(未显示)和匿名函数传递给它们:
283
335
336
+ {% tabs list %}
337
+ {% tab 'Scala 2 and 3' for=higher-order %}
284
338
``` scala
285
339
a.dropWhile(_ < 25 )
286
340
a.filter(_ < 25 )
@@ -289,23 +343,52 @@ a.filter(_ < 30).map(_ * 10)
289
343
nums.sortWith(_ < _)
290
344
nums.sortWith(_ > _)
291
345
```
346
+ {% endtab %}
347
+ {% endtabs %}
292
348
293
349
` match ` 表达式让您可以使用模式匹配,它们确实是返回值的 _ 表达式_ :
294
350
351
+ {% tabs match class=tabs-scala-version %}
352
+ {% tab 'Scala 2' for=match %}
353
+ ``` scala
354
+ val numAsString = i match {
355
+ case 1 | 3 | 5 | 7 | 9 => " odd"
356
+ case 2 | 4 | 6 | 8 | 10 => " even"
357
+ case _ => " too big"
358
+ }
359
+ ```
360
+ {% endtab %}
361
+
362
+ {% tab 'Scala 3' for=match %}
295
363
``` scala
296
364
val numAsString = i match
297
365
case 1 | 3 | 5 | 7 | 9 => " odd"
298
366
case 2 | 4 | 6 | 8 | 10 => " even"
299
367
case _ => " too big"
300
368
```
369
+ {% endtab %}
370
+ {% endtabs %}
301
371
302
372
因为它们可以返回值,所以它们经常被用作方法的主体:
303
373
374
+ {% tabs match-body class=tabs-scala-version %}
375
+ {% tab 'Scala 2' for=match-body %}
376
+ ``` scala
377
+ def isTruthy (a : Matchable ) = a match {
378
+ case 0 | " " => false
379
+ case _ => true
380
+ }
381
+ ```
382
+ {% endtab %}
383
+
384
+ {% tab 'Scala 3' for=match-body %}
304
385
``` scala
305
386
def isTruthy (a : Matchable ) = a match
306
387
case 0 | " " => false
307
388
case _ => true
308
389
```
390
+ {% endtab %}
391
+ {% endtabs %}
309
392
310
393
## 9) 生态系统库
311
394
@@ -373,6 +456,8 @@ _安全_ 与几个新的和改变的特性有关:
373
456
374
457
_ 人体工程学_ 的好例子是枚举和扩展方法,它们以非常易读的方式添加到 Scala 3 中:
375
458
459
+ {% tabs extension %}
460
+ {% tab 'Scala 3 Only' for=extension %}
376
461
``` scala
377
462
// 枚举
378
463
enum Color :
@@ -384,6 +469,8 @@ extension (c: Circle)
384
469
def diameter : Double = c.radius * 2
385
470
def area : Double = math.Pi * c.radius * c.radius
386
471
```
472
+ {% endtab %}
473
+ {% endtabs %}
387
474
388
475
_ 性能_ 涉及几个方面。
389
476
其中之一是 [ 不透明类型] [ opaque-types ] 。
0 commit comments