鍍金池/ 教程/ Scala/ 柯里化函數(shù)
包對(duì)象
Ordered Trait
組合和繼承–定義 final 成員
基本數(shù)據(jù)類(lèi)型
Match 表達(dá)式
類(lèi)和對(duì)象 (三)
操作基本數(shù)據(jù)類(lèi)型
for 表達(dá)式
組合和繼承–重載成員函數(shù)和方法
類(lèi)和對(duì)象 (二)
組合和繼承–定義 factory 對(duì)象
組合和繼承–多態(tài)和動(dòng)態(tài)綁定
Trait 的基本概念
if 表達(dá)式
組合和繼承–抽象類(lèi)
函數(shù)–函數(shù)字面量的一些簡(jiǎn)化寫(xiě)法
while 循環(huán)
組合和繼承–使用組合還是繼承?
訪問(wèn)控制修飾符
Trait 示例–Rectangular 對(duì)象
組合和繼承–定義參數(shù)化成員變量
組合和繼承–定義無(wú)參數(shù)方法
類(lèi)和對(duì)象 (一)
函數(shù)–閉包
函數(shù)–類(lèi)成員函數(shù)
Scala 基本數(shù)據(jù)類(lèi)型的實(shí)現(xiàn)方法
try 表達(dá)式處理異常
選擇瘦接口還是胖接口設(shè)計(jì)?
組合和繼承–小結(jié)
創(chuàng)建新的控制結(jié)構(gòu)
使用 import
為訪問(wèn)控制修飾符添加作用域
Scala 的類(lèi)層次關(guān)系
類(lèi)和對(duì)象 (五)
傳名參數(shù)
柯里化函數(shù)
函數(shù)–頭等公民
組合和組合和繼承–定義 heighten 和 widen 函數(shù)
使用 Package–將代碼放入包中
隱含的 import
所有類(lèi)的公共子類(lèi)–底層類(lèi)型
進(jìn)一步 Scala
函數(shù)–局部函數(shù)
引用包中的代碼
組合和繼承–使用 override 修飾符
組合和繼承–實(shí)現(xiàn)類(lèi) Element 的 above,beside 和 toString()方法
類(lèi)和對(duì)象 (四)
函數(shù)–尾遞歸
沒(méi)有“break”和“continue”的日子
組合和繼承–調(diào)用基類(lèi)構(gòu)造函數(shù)
減低代碼重復(fù)
函數(shù)–函數(shù)–可變參數(shù),命名參數(shù),缺省參數(shù)
起步 Scala
組合和繼承–擴(kuò)展類(lèi)
函數(shù)–部分應(yīng)用的函數(shù)
開(kāi)始神奇的 Scala編程之旅
組合和繼承–概述
Trait 用來(lái)實(shí)現(xiàn)可疊加的修改操作

柯里化函數(shù)

前面我們說(shuō)過(guò),Scala 允許程序員自己新創(chuàng)建一些控制結(jié)構(gòu),并且可以使得這些控制結(jié)構(gòu)在語(yǔ)法看起來(lái)和 Scala 內(nèi)置的控制結(jié)構(gòu)一樣,在 Scala 中需要借助于柯里化(Currying),柯里化是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。

下面先給出一個(gè)普通的非柯里化的函數(shù)定義,實(shí)現(xiàn)一個(gè)加法函數(shù):

scala> def plainOldSum(x:Int,y:Int) = x + y
plainOldSum: (x: Int, y: Int)Int
scala> plainOldSum(1,2)
res0: Int = 3

下面在使用“柯里化”技術(shù)來(lái)定義這個(gè)加法函數(shù),原來(lái)函數(shù)使用一個(gè)參數(shù)列表,“柯里化”把函數(shù)定義為多個(gè)參數(shù)列表:

scala> def curriedSum(x:Int)(y:Int) = x + y
curriedSum: (x: Int)(y: Int)Int
scala> curriedSum (1)(2)
res0: Int = 3

當(dāng)你調(diào)用 curriedSum (1)(2)時(shí),實(shí)際上是依次調(diào)用兩個(gè)普通函數(shù)(非柯里化函數(shù)),第一次調(diào)用使用一個(gè)參數(shù) x,返回一個(gè)函數(shù)類(lèi)型的值,第二次使用參數(shù)y調(diào)用這個(gè)函數(shù)類(lèi)型的值,我們使用下面兩個(gè)分開(kāi)的定義在模擬 curriedSum 柯里化函數(shù):

首先定義第一個(gè)函數(shù):

scala> def first(x:Int) = (y:Int) => x + y
first: (x: Int)Int => Int

然后我們使用參數(shù)1調(diào)用這個(gè)函數(shù)來(lái)生成第二個(gè)函數(shù)(回憶前面定義的閉包)。

scala> val second=first(1)
second: Int => Int = <function1>
scala> second(2)
res1: Int = 3

first,second的定義演示了柯里化函數(shù)的調(diào)用過(guò)程,它們本身和 curriedSum 沒(méi)有任何關(guān)系,但是我們可以使用 curriedSum 來(lái)定義 second,如下:

scala> val onePlus = curriedSum(1)_
onePlus: Int => Int = <function1>

下劃線“_” 作為第二參數(shù)列表的占位符, 這個(gè)定義的返回值為一個(gè)函數(shù),當(dāng)調(diào)用時(shí)會(huì)給調(diào)用的參數(shù)加一。

scala> onePlus(2)
res2: Int = 3

通過(guò)柯里化,你還可以定義多個(gè)類(lèi)似 onePlus 的函數(shù),比如 twoPlus

scala> val twoPlus = curriedSum(2) _
twoPlus: Int => Int = <function1>
scala> twoPlus(2)
res3: Int = 4