Skip to content

Commit 31a1150

Browse files
authored
translated according to the newest version. (#2647)
1 parent 85686bb commit 31a1150

File tree

1 file changed

+77
-28
lines changed

1 file changed

+77
-28
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Given Instances and Using Clauses
2+
title: Given 实例和 Using 语句
33
type: section
44
description: This page demonstrates how to use 'given' instances and 'using' clauses in Scala 3.
55
num: 59
@@ -12,16 +12,24 @@ layout: multipage-overview
1212
permalink: "/zh-cn/scala3/book/:title.html"
1313
---
1414

15-
Scala 3 offers two important feature for contextual abstraction:
1615

17-
- **Using Clauses** allow you to specify parameters that, at the call site, can be omitted by the programmer and should be automatically provided by the context.
18-
- **Given Instances** let you define terms that can be used by the Scala compiler to fill in the missing arguments.
16+
<h5>使用上下文抽象<span class="tag tag-inline">仅限Scala 3</span></h5>
1917

20-
## Using Clauses
21-
When designing a system, often context information like _configuration_ or settings need to be provided to the different components of your system.
22-
One common way to achieve this is by passing the configuration as additional argument to your methods.
18+
Scala 3 提供了两个重要的上下文抽象特性:
19+
20+
- **Using 语句** 允许你指定参数,这些参数程序员可以在调用时省略,这些参数由上下文自动提供。
21+
- **Given 实例** 让您定义 Scala 编译器可以用来填充缺失参数的术语。
22+
23+
## Using 语句
24+
25+
在设计系统时,通常需要向系统的不同组件提供上下文信息,如_配置_或设置。
26+
实现此目的的一种常见方法是将配置作为附加参数传递给您的方法。
27+
28+
在下面的示例中,我们定义了一个样例类 `Config` 来模拟一些网站配置并在不同的方法中传递它。
29+
30+
{% tabs nonusing %}
31+
{% tab 'Scala 2 and 3' %}
2332

24-
In the following example, we define a case class `Config` to model some website configuration and pass it around in the different methods.
2533
```scala
2634
case class Config(port: Int, baseUrl: String)
2735

@@ -33,11 +41,20 @@ def renderWidget(items: List[String], c: Config): String = ???
3341
val config = Config(8080, "docs.scala-lang.org")
3442
renderWebsite("/home", config)
3543
```
36-
Let us assume that the configuration does not change throughout most of our code base.
37-
Passing `c` to each and every method call (like `renderWidget`) becomes very tedious and makes our program more difficult to read, since we need to ignore the `c` argument.
3844

39-
#### Using `using` to mark parameters as contextual
40-
In Scala 3, we can mark some of the parameters of our methods as _contextual_.
45+
{% endtab %}
46+
{% endtabs %}
47+
48+
让我们假设配置在我们的大部分代码库中都没有改变。
49+
`c` 传递给每个方法调用(如 `renderWidget`)变得非常乏味并且使我们的程序更难阅读,因为我们需要忽略 `c` 参数。
50+
51+
#### 使用 `using` 将参数标记为上下文
52+
53+
在 Scala 3 中,我们可以将方法的一些参数标记为_上下文_
54+
55+
{% tabs using1 %}
56+
{% tab 'Scala 3 Only' %}
57+
4158
```scala
4259
def renderWebsite(path: String)(using c: Config): String =
4360
"<html>" + renderWidget(List("cart")) + "</html>"
@@ -46,13 +63,20 @@ def renderWebsite(path: String)(using c: Config): String =
4663

4764
def renderWidget(items: List[String])(using c: Config): String = ???
4865
```
49-
By starting a parameter section with the keyword `using`, we tell the Scala compiler that at the callsite it should automatically find an argument with the correct type.
50-
The Scala compiler thus performs **term inference**.
5166

52-
In our call to `renderWidget(List("cart"))` the Scala compiler will see that there is a term of type `Config` in scope (the `c`) and automatically provide it to `renderWidget`.
53-
So the program is equivalent to the one above.
67+
{% endtab %}
68+
{% endtabs %}
69+
70+
通过使用关键字 `using` 开始参数部分,我们告诉 Scala 编译器它应该在调用处自动找到具有正确类型的参数。
71+
因此,Scala 编译器执行**术语推断**
72+
73+
在我们对 `renderWidget(List("cart"))` 的调用中,Scala 编译器将看到作用域(`c`)中有一个类型为 `Config` 的术语,并自动将其提供给 `renderWidget`
74+
所以程序等同于上面的程序。
5475

55-
In fact, since we do not need to refer to `c` in our implementation of `renderWebsite` anymore, we can even omit its name in the signature:
76+
事实上,由于我们不再需要在 `renderWebsite` 的实现中引用 `c`,我们甚至可以在签名中省略它的名字:
77+
78+
{% tabs using2 %}
79+
{% tab 'Scala 3 Only' %}
5680

5781
```scala
5882
// no need to come up with a parameter name
@@ -61,22 +85,37 @@ def renderWebsite(path: String)(using Config): String =
6185
"<html>" + renderWidget(List("cart")) + "</html>"
6286
```
6387

64-
#### Explicitly providing contextual arguments
65-
We have seen how to _abstract_ over contextual parameters and that the Scala compiler can provide arguments automatically for us.
66-
But how can we specify which configuration to use for our call to `renderWebsite`?
88+
{% endtab %}
89+
{% endtabs %}
90+
91+
#### 明确提供上下文参数
92+
93+
我们已经了解了如何_抽象_上下文参数,并且 Scala 编译器可以自动为我们提供参数。
94+
但是我们如何指定调用 `renderWebsite` 时使用的配置呢?
6795

68-
Like we specified our parameter section with `using`, we can also explicitly provide contextual arguments with `using:`
96+
就像我们使用 `using` 指定参数部分一样,我们也可以使用 `using` 显式提供上下文参数:
97+
98+
{% tabs using3 %}
99+
{% tab 'Scala 3 Only' %}
69100

70101
```scala
71102
renderWebsite("/home")(using config)
72103
```
73-
Explicitly providing contextual parameters can be useful if we have multiple different values in scope that would make sense and we want to make sure that the correct one is passed to the function.
74104

75-
For all other cases, as we will see in the next Section, there is also another way to bring contextual values into scope.
105+
{% endtab %}
106+
{% endtabs %}
107+
108+
如果我们在范围内有多个有意义的不同值,并且我们希望确保将正确的值传递给函数,则显式提供上下文参数可能很有用。
109+
110+
对于所有其他情况,正如我们将在下一节中看到的,还有另一种方法可以将上下文值引入范围。
76111

77-
## Given Instances
78-
We have seen that we can explicitly pass arguments as contextual parameters by marking the argument section of the _call_ with `using`.
79-
However, if there is _a single canonical value_ for a particular type, there is another preferred way to make it available to the Scala compiler: by marking it as `given`.
112+
## Give 实例
113+
114+
我们已经看到,我们可以通过使用 `using` 标记 _调用_的参数部分来显式地将参数作为上下文参数传递。
115+
但是,如果某个特定类型有一个_单一的规范值_,则还有另一种首选方法可以使其对 Scala 编译器可用:将其标记为 `given`
116+
117+
{% tabs given1 %}
118+
{% tab 'Scala 3 Only' %}
80119

81120
```scala
82121
val config = Config(8080, "docs.scala-lang.org")
@@ -88,15 +127,25 @@ given Config = config
88127
// this is the value the Scala compiler will infer
89128
// as argument to contextual parameters of type Config
90129
```
91-
In the above example we specify that whenever a contextual parameter of type `Config` is omitted in the current scope, the compiler should infer `config` as an argument.
92130

93-
Having defined a given for `Config`, we can simply call `renderWebsite`:
131+
{% endtab %}
132+
{% endtabs %}
133+
134+
在上面的示例中,我们指定每当在当前范围内省略 `Config` 类型的上下文参数时,编译器应该将 `config` 推断为参数。
135+
136+
`Config` 定义了 given,我们可以简单地调用 `renderWebsite`
137+
138+
{% tabs given2 %}
139+
{% tab 'Scala 3 Only' %}
94140

95141
```scala
96142
renderWebsite("/home")
97143
// ^^^^^
98144
// again no argument
99145
```
100146

147+
{% endtab %}
148+
{% endtabs %}
149+
101150
[reference]: {{ site.scala3ref }}/overview.html
102151
[blog-post]: /2020/11/06/explicit-term-inference-in-scala-3.html

0 commit comments

Comments
 (0)