Skip to content

Commit 3423ca7

Browse files
authored
Merge pull request scala#1173 from declan94/currying
zh-cn for Tour: multiple parameter lists
2 parents 46c9e6a + 8336f2b commit 3423ca7

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

_zh-cn/tour/multiple-parameter-lists.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: tour
3-
title: Multiple Parameter Lists (Currying)
3+
title: 多参数列表(柯里化)
44

55
discourse: false
66

@@ -13,3 +13,71 @@ language: zh-cn
1313
next-page: case-classes
1414
previous-page: nested-functions
1515
---
16+
17+
方法可以定义多个参数列表,当使用较少的参数列表调用多参数列表的方法时,会产生一个新的函数,该函数接收剩余的参数列表作为其参数。这被称为[柯里化](https://zh.wikipedia.org/wiki/%E6%9F%AF%E9%87%8C%E5%8C%96)
18+
19+
下面是一个例子,在Scala集合中定义的特质[Traversable](/zh-cn/overviews/collections/trait-traversable.html)
20+
21+
```
22+
def foldLeft[B](z: B)(op: (B, A) => B): B
23+
```
24+
25+
`foldLeft`从左到右,以此将一个二元运算`op`应用到初始值`z`和该迭代器(traversable)的所有元素上。以下是该函数的一个用例:
26+
27+
从初值0开始, 这里 `foldLeft` 将函数 `(m, n) => m + n` 依次应用到列表中的每一个元素和之前累积的值上。
28+
29+
```tut
30+
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
31+
val res = numbers.foldLeft(0)((m, n) => m + n)
32+
print(res) // 55
33+
```
34+
35+
多参数列表有更复杂的调用语法,因此应该谨慎使用,建议的使用场景包括:
36+
37+
#### 单一的函数参数
38+
在某些情况下存在单一的函数参数时,例如上述例子`foldLeft`中的`op`,多参数列表可以使得传递匿名函数作为参数的语法更为简洁。如果不使用多参数列表,代码可能像这样:
39+
40+
```
41+
numbers.foldLeft(0, {(m: Int, n: Int) => m + n})
42+
```
43+
44+
注意使用多参数列表时,我们还可以利用Scala的类型推断来让代码更加简洁(如下所示),而如果没有多参数列表,这是不可能的。
45+
46+
```
47+
numbers.foldLeft(0)(_ + _)
48+
```
49+
像上述语句这样,我们可以给定多参数列表的一部分参数列表(如上述的`z`)来形成一个新的函数(partially applied function),达到复用的目的,如下所示:
50+
51+
```tut
52+
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
53+
val numberFunc = numbers.foldLeft(List[Int]())_
54+
55+
val squares = numberFunc((xs, x) => xs:+ x*x)
56+
print(squares.toString()) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)
57+
58+
val cubes = numberFunc((xs, x) => xs:+ x*x*x)
59+
print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)
60+
```
61+
62+
最后,`foldLeft``foldRight` 可以按以下任意一种形式使用,
63+
```tut
64+
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
65+
66+
numbers.foldLeft(0)((sum, item) => sum + item) // Generic Form
67+
numbers.foldRight(0)((sum, item) => sum + item) // Generic Form
68+
69+
numbers.foldLeft(0)(_+_) // Curried Form
70+
numbers.foldRight(0)(_+_) // Curried Form
71+
72+
(0 /: numbers)(_+_) // Used in place of foldLeft
73+
(numbers :\ 0)(_+_) // Used in place of foldRight
74+
```
75+
76+
77+
#### 隐式(implicit)参数
78+
如果要指定参数列表中的某些参数为隐式(implicit),应该使用多参数列表。例如:
79+
80+
```
81+
def execute(arg: Int)(implicit ec: ExecutionContext) = ???
82+
```
83+

0 commit comments

Comments
 (0)