1. 程式人生 > >Scala 基礎教程10 -- 多個引數列表 (CURRYING)

Scala 基礎教程10 -- 多個引數列表 (CURRYING)

10 多個引數列表(CURRYING)

方法可以定義多個引數列表。當使用較少數量的引數列表呼叫方法時,這將產生一個函式,將缺少的引數列表作為其引數。這正式稱為currying。 這是一個示例,在Scala集合的Traversable trait中定義:

def foldLeft[B](z: B)(op: (B, A) => B): B

foldLeft將二元運算子op應用於初始值z以及此可遍歷的所有元素,從左到右。下面顯示的是它的用法示例。 從初始值0開始,foldLeft此處將函式應用於(m, n) => m + nList中的每個元素和先前的累計值。

val numbers = List
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) print(res) // 55

多個引數列表具有更詳細的呼叫語法; 因此應該謹慎使用。建議的用例包括:

10.1 單一功能引數

在單個功能引數op的情況下,foldLeft如上所述,多個引數列表允許簡明的語法將匿名函式傳遞給該方法。如果沒有多個引數列表,程式碼將如下所示:

numbers.foldLeft(0, {(m: Int, n: Int) => m + n})

請注意,這裡使用多個引數列表還允許我們利用Scala型別推斷使程式碼更簡潔,如下所示; 這在非咖哩定義中是不可能的。

numbers.foldLeft(0)(_ + _)

上面的語句numbers.foldLeft(0)(_ + _)允許我們修復引數z並傳遞部分函式並重用它,如下所示:

val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val numberFunc = numbers.foldLeft(List[Int]())_

val squares = numberFunc((xs, x) => xs:+ x*x)
print(squares.toString()) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

val cubes =
numberFunc((xs, x) => xs:+ x*x*x) print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)

最後,foldLeft並且foldRight可以在任何下列用語的使用,

val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
numbers.foldLeft(0)((sum, item) => sum + item) // Generic Form
numbers.foldRight(0)((sum, item) => sum + item) // Generic Form
numbers.foldLeft(0)(_+_) // Curried Form
numbers.foldRight(0)(_+_) // Curried Form
(0 /: numbers)(_+_) // Used in place of foldLeft
(numbers :\ 0)(_+_) // Used in place of foldRight

10.2 隱含引數

要將引數列表中的某些引數指定為implicit,應使用多個引數列表。一個例子是:

def execute(arg: Int)(implicit ec: ExecutionContext) = ???