Scala 基礎教程10 -- 多個引數列表 (CURRYING)
阿新 • • 發佈:2018-12-19
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) = ???