Skip to content

Commit ac9eac8

Browse files
authored
Merge pull request #1193 from realwunan/implicit-parameters
zh-cn for Scala Tour: implicit-parameters.md
2 parents f598511 + abe8d8f commit ac9eac8

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

_zh-cn/tour/implicit-parameters.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: tour
3-
title: Implicit Parameters
3+
title: 隐式参数
44

55
discourse: false
66

@@ -13,3 +13,62 @@ language: zh-cn
1313
next-page: implicit-conversions
1414
previous-page: self-types
1515
---
16+
17+
方法可以具有 _隐式_ 参数列表,由参数列表开头的 _implicit_ 关键字标记。 如果参数列表中的参数没有像往常一样传递, Scala 将查看它是否可以获得正确类型的隐式值,如果可以,则自动传递。
18+
19+
Scala 将查找这些参数的位置分为两类:
20+
21+
* Scala 在调用包含有隐式参数块的方法时,将首先查找可以直接访问的隐式定义和隐式参数 (无前缀)。
22+
* 然后,它在所有伴生对象中查找与隐式候选类型相关的有隐式标记的成员。
23+
24+
更加详细的关于 Scala 到哪里查找隐式参数的指南请参考 [常见问题](//docs.scala-lang.org/tutorials/FAQ/finding-implicits.html)
25+
26+
在下面的例子中,我们定义了一个方法 `sum`,它使用 Monoid 类的 `add``unit` 方法计算一个列表中元素的总和。 请注意,隐式值不能是顶级值。
27+
28+
```tut
29+
abstract class Monoid[A] {
30+
def add(x: A, y: A): A
31+
def unit: A
32+
}
33+
34+
object ImplicitTest {
35+
implicit val stringMonoid: Monoid[String] = new Monoid[String] {
36+
def add(x: String, y: String): String = x concat y
37+
def unit: String = ""
38+
}
39+
40+
implicit val intMonoid: Monoid[Int] = new Monoid[Int] {
41+
def add(x: Int, y: Int): Int = x + y
42+
def unit: Int = 0
43+
}
44+
45+
def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
46+
if (xs.isEmpty) m.unit
47+
else m.add(xs.head, sum(xs.tail))
48+
49+
def main(args: Array[String]): Unit = {
50+
println(sum(List(1, 2, 3))) // uses IntMonoid implicitly
51+
println(sum(List("a", "b", "c"))) // uses StringMonoid implicitly
52+
}
53+
}
54+
```
55+
56+
`Monoid` 定义了一个名为 `add` 的操作,它将一对 `A` 类型的值相加并返回一个 `A`,以及一个名为 `unit` 的操作,用来创建一个(特定的)`A` 类型的值。
57+
58+
为了说明隐式参数如何工作,我们首先分别为字符串和整数定义 Monoid 实例, `StringMonoid``IntMonoid``implicit` 关键字表示可以隐式使用相应的对象。
59+
60+
方法 `sum` 接受一个 `List[A]`,并返回一个 `A` 的值,它从 `unit` 中取初始的 `A` 值,并使用 `add` 方法依次将列表中的下一个 `A` 值相加。在这里将参数 `m` 定义为隐式意味着,如果 Scala 可以找到隐式 `Monoid[A]` 用于隐式参数 `m`,我们在调用 `sum` 方法时只需要传入 `xs` 参数。
61+
62+
`main` 方法中我们调用了 `sum` 方法两次,并且只传入参数 `xs`。 Scala 会在上例的上下文范围内寻找隐式值。 第一次调用 `sum` 方法的时候传入了一个 `List[Int]` 作为 `xs` 的值,这意味着此处类型 `A``Int`。 隐式参数列表 `m` 被省略了,因此 Scala 将查找类型为 `Monoid[Int]` 的隐式值。 第一查找规则如下
63+
64+
> Scala 在调用包含有隐式参数块的方法时,将首先查找可以直接访问的隐式定义和隐式参数 (无前缀)。
65+
66+
`intMonoid` 是一个隐式定义,可以在`main`中直接访问。 并且它的类型也正确,因此它会被自动传递给 `sum` 方法。
67+
68+
第二次调用 `sum` 方法的时候传入一个 `List[String]`,这意味着此处类型 `A``String`。 与查找 `Int` 型的隐式参数时类似,但这次会找到 `stringMonoid`,并自动将其作为 `m` 传入。
69+
70+
该程序将输出
71+
```
72+
6
73+
abc
74+
```

0 commit comments

Comments
 (0)