Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modified Chinese ca-context-bounds.md #2823

Merged
90 changes: 75 additions & 15 deletions _zh-cn/overviews/scala3-book/ca-context-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,101 @@ permalink: "/zh-cn/scala3/book/:title.html"
---


{% comment %}
- TODO: define "context parameter"
- TODO: define "synthesized" and "synthesized arguments"
{% endcomment %}


在许多情况下,_上下文参数_的名称不必明确提及,因为它仅由编译器在其他上下文参数的合成参数中使用。
在许多情况下,[上下文参数]({% link _overviews/scala3-book/ca-context-parameters.md %}#context-parameters) 的名称不必明确提及,因为它仅由编译器在其他上下文参数的合成参数中使用。
benluo marked this conversation as resolved.
Show resolved Hide resolved
在这种情况下,您不必定义参数名称,只需提供参数类型即可。

## 背景

例如,这个 `maximum` 方法接受 `Ord` 类型的_上下文参数_,只是将它作为参数传递给 `max`
例如,假设一个 `maxElement` 方法返回一个集合里的最大值

{% tabs context-bounds-max-named-param class=tabs-scala-version %}
{% tab 'Scala 2' %}
```scala
def maximum[A](xs: List[A])(using ord: Ord[A]): A =
xs.reduceLeft(max(ord))
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
as.reduceLeft(max(_, _)(ord))
```
{% endtab %}
{% tab 'Scala 3' %}
```scala
def maxElement[A](as: List[A])(using ord: Ord[A]): A =
as.reduceLeft(max(_, _)(using ord))
```
{% endtab %}
{% endtabs %}

`maxElement` 方法把一个 `Ord[A]` 类的 _上下文参数_ 当作参数只传给 `max` 方法。
benluo marked this conversation as resolved.
Show resolved Hide resolved

在该代码中,参数名称 `ord` 实际上不是必需的;它可以作为推断参数传递给 `max`,因此您只需声明 `maximum` 使用的类型 `Ord[A]` 而不必给它命名:
为了完整起见,以下是 `max` 和 `Ord` 的定义(请注意,在实践中我们会在 `List` 上使用现有的方法 `max`,
benluo marked this conversation as resolved.
Show resolved Hide resolved
但我们为了说明目的而编造了这个例子):

{% tabs context-bounds-max-ord class=tabs-scala-version %}
{% tab 'Scala 2' %}
```scala
def maximum[A](xs: List[A])(using Ord[A]): A =
xs.reduceLeft(max)
/** Defines how to compare values of type `A` */
trait Ord[A] {
def greaterThan(a1: A, a2: A): Boolean
}

/** Returns the maximum of two values */
def max[A](a1: A, a2: A)(implicit ord: Ord[A]): A =
if (ord.greaterThan(a1, a2)) a1 else a2
```
{% endtab %}

{% tab 'Scala 3' %}
```scala
/** Defines how to compare values of type `A` */
trait Ord[A]:
def greaterThan(a1: A, a2: A): Boolean

/** Returns the maximum of two values */
def max[A](a1: A, a2: A)(using ord: Ord[A]): A =
if ord.greaterThan(a1, a2) then a1 else a2
```
{% endtab %}
{% endtabs %}

`max` 方法用了类 `Ord[A]` 的上下文参数, 就像 `maxElement` 方法。
benluo marked this conversation as resolved.
Show resolved Hide resolved

## 省略上下文参数

因为 `ord` 是 `max` 方法的上下文参数,当我们调用方法 `max` 时, 编译器可以在 `maxElement` 的实现中为我们提供它:

{% tabs context-bounds-context class=tabs-scala-version %}
{% tab 'Scala 2' %}
```scala
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
as.reduceLeft(max(_, _))
```
{% endtab %}

{% tab 'Scala 3' %}
```scala
def maxElement[A](as: List[A])(using Ord[A]): A =
as.reduceLeft(max(_, _))
```

注意,因为我们不用显示传递给 `max` 方法,我们可以在 `maxElement` 定义里不命名。
这是 _匿名上下文参数_ 。
{% endtab %}
{% endtabs %}

## 上下文绑定

鉴于此背景,_上下文绑定_是一种简写语法,用于表达“依赖于类型参数的上下文参数”模式。
鉴于此背景,_上下文绑定_ 是一种简写语法,用于表达“依赖于类型参数的上下文参数”模式。

使用上下文绑定,`maximum` 方法可以这样写:
benluo marked this conversation as resolved.
Show resolved Hide resolved

{% tabs context-bounds-max-rewritten %}
{% tab 'Scala 2 and 3' %}
```scala
def maximum[A: Ord](xs: List[A]): A = xs.reduceLeft(max)
def maxElement[A: Ord](as: List[A]): A =
as.reduceLeft(max(_, _))
```
{% endtab %}
{% endtabs %}

方法或类的类型参数 `A`,有类似 `:Ord` 的绑定,它表示有 `Ord[A]` 的上下文参数。
在后台,编译器将此语法转换为“背景”部分中显示的语法。

有关上下文绑定的更多信息,请参阅 Scala 常见问题解答的 [“什么是上下文绑定?”](https://docs.scala-lang.org/tutorials/FAQ/context-bounds.html) 部分。