@@ -14,41 +14,101 @@ permalink: "/zh-cn/scala3/book/:title.html"
14
14
---
15
15
16
16
17
- {% comment %}
18
- - TODO: define "context parameter"
19
- - TODO: define "synthesized" and "synthesized arguments"
20
- {% endcomment %}
21
-
22
-
23
- 在许多情况下,_ 上下文参数_的名称不必明确提及,因为它仅由编译器在其他上下文参数的合成参数中使用。
17
+ 在许多情况下,[ 上下文参数] ({% link _ overviews/scala3-book/ca-context-parameters.md %}#context-parameters) 的名称不必显式提及,因为它仅在编译器为其他上下文参数合成实参的时候用到。
24
18
在这种情况下,您不必定义参数名称,只需提供参数类型即可。
25
19
26
20
## 背景
27
21
28
- 例如,这个 ` maximum ` 方法接受 ` Ord ` 类型的_上下文参数 _ ,只是将它作为参数传递给 ` max ` :
22
+ 例如,假设一个 ` maxElement ` 方法返回一个集合里的最大值 :
29
23
24
+ {% tabs context-bounds-max-named-param class=tabs-scala-version %}
25
+ {% tab 'Scala 2' %}
30
26
``` scala
31
- def maximum [A ](xs : List [A ])(using ord : Ord [A ]): A =
32
- xs .reduceLeft(max(ord))
27
+ def maxElement [A ](as : List [A ])(implicit ord : Ord [A ]): A =
28
+ as .reduceLeft(max(_, _) (ord))
33
29
```
30
+ {% endtab %}
31
+ {% tab 'Scala 3' %}
32
+ ``` scala
33
+ def maxElement [A ](as : List [A ])(using ord : Ord [A ]): A =
34
+ as.reduceLeft(max(_, _)(using ord))
35
+ ```
36
+ {% endtab %}
37
+ {% endtabs %}
38
+
39
+ 上面这个 ` maxElement ` 方法只接受一个类型为 ` Ord[A] ` 的 _ 上下文参数_ 并将其作为实参传给 ` max ` 方法。
34
40
35
- 在该代码中,参数名称 ` ord ` 实际上不是必需的;它可以作为推断参数传递给 ` max ` ,因此您只需声明 ` maximum ` 使用的类型 ` Ord[A] ` 而不必给它命名:
41
+ 完整起见,以下是 ` max ` 和 ` Ord ` 的定义(注意,在实践中我们会使用 ` List ` 中已有的 ` max ` 方法 ,
42
+ 但我们为了说明目的而编造了这个例子):
36
43
44
+ {% tabs context-bounds-max-ord class=tabs-scala-version %}
45
+ {% tab 'Scala 2' %}
37
46
``` scala
38
- def maximum [A ](xs : List [A ])(using Ord [A ]): A =
39
- xs.reduceLeft(max)
47
+ /** Defines how to compare values of type `A` */
48
+ trait Ord [A ] {
49
+ def greaterThan (a1 : A , a2 : A ): Boolean
50
+ }
51
+
52
+ /** Returns the maximum of two values */
53
+ def max [A ](a1 : A , a2 : A )(implicit ord : Ord [A ]): A =
54
+ if (ord.greaterThan(a1, a2)) a1 else a2
40
55
```
56
+ {% endtab %}
57
+
58
+ {% tab 'Scala 3' %}
59
+ ``` scala
60
+ /** Defines how to compare values of type `A` */
61
+ trait Ord [A ]:
62
+ def greaterThan (a1 : A , a2 : A ): Boolean
63
+
64
+ /** Returns the maximum of two values */
65
+ def max [A ](a1 : A , a2 : A )(using ord : Ord [A ]): A =
66
+ if ord.greaterThan(a1, a2) then a1 else a2
67
+ ```
68
+ {% endtab %}
69
+ {% endtabs %}
70
+
71
+ ` max ` 方法用了类型为 ` Ord[A] ` 的上下文参数, 就像 ` maxElement ` 方法一样。
72
+
73
+ ## 省略上下文参数
74
+
75
+ 因为 ` ord ` 是 ` max ` 方法的上下文参数,当我们调用方法 ` max ` 时, 编译器可以在 ` maxElement ` 的实现中为我们提供它:
76
+
77
+ {% tabs context-bounds-context class=tabs-scala-version %}
78
+ {% tab 'Scala 2' %}
79
+ ``` scala
80
+ def maxElement [A ](as : List [A ])(implicit ord : Ord [A ]): A =
81
+ as.reduceLeft(max(_, _))
82
+ ```
83
+ {% endtab %}
84
+
85
+ {% tab 'Scala 3' %}
86
+ ``` scala
87
+ def maxElement [A ](as : List [A ])(using Ord [A ]): A =
88
+ as.reduceLeft(max(_, _))
89
+ ```
90
+
91
+ 注意,因为我们不用显示传递给 ` max ` 方法,我们可以在 ` maxElement ` 定义里不命名。
92
+ 这是 _ 匿名上下文参数_ 。
93
+ {% endtab %}
94
+ {% endtabs %}
41
95
42
96
## 上下文绑定
43
97
44
- 鉴于此背景,_ 上下文绑定_是一种简写语法 ,用于表达“依赖于类型参数的上下文参数”模式。
98
+ 鉴于此背景,_ 上下文绑定 _ 是一种简写语法 ,用于表达“依赖于类型参数的上下文参数”模式。
45
99
46
- 使用上下文绑定,` maximum ` 方法可以这样写:
100
+ 使用上下文绑定,` maxElement ` 方法可以这样写:
47
101
102
+ {% tabs context-bounds-max-rewritten %}
103
+ {% tab 'Scala 2 and 3' %}
48
104
``` scala
49
- def maximum [A : Ord ](xs : List [A ]): A = xs.reduceLeft(max)
105
+ def maxElement [A : Ord ](as : List [A ]): A =
106
+ as.reduceLeft(max(_, _))
50
107
```
108
+ {% endtab %}
109
+ {% endtabs %}
51
110
52
111
方法或类的类型参数 ` A ` ,有类似 ` :Ord ` 的绑定,它表示有 ` Ord[A] ` 的上下文参数。
112
+ 在后台,编译器将此语法转换为“背景”部分中显示的语法。
53
113
54
114
有关上下文绑定的更多信息,请参阅 Scala 常见问题解答的 [ “什么是上下文绑定?”] ( https://docs.scala-lang.org/tutorials/FAQ/context-bounds.html ) 部分。
0 commit comments