介紹Scala的第一類(lèi)函數(shù)
Scala擁有***類(lèi)函數(shù):first-class function。你不僅可以定義函數(shù)和調(diào)用它們,還可以把函數(shù)寫(xiě)成沒(méi)有名字的文本:literal并把它們像值:value那樣傳遞。我們?cè)诘?章介紹了函數(shù)文本并在第42頁(yè)的圖2.2里展示了基本語(yǔ)法。
51CTO編輯推薦:Scala編程語(yǔ)言專(zhuān)題
函數(shù)文本被編譯進(jìn)一個(gè)類(lèi),類(lèi)在運(yùn)行期實(shí)例化的時(shí)候是一個(gè)函數(shù)值:function value。任何函數(shù)值都是某個(gè)擴(kuò)展了若干scala包的FunctionN特質(zhì)之一的類(lèi)的實(shí)例,如Function0是沒(méi)有參數(shù)的函數(shù),F(xiàn)unction1是有一個(gè)參數(shù)的函數(shù)等等。每個(gè)FunctionN特質(zhì)有一個(gè)apply方法用來(lái)調(diào)用函數(shù)。因此函數(shù)文本和值的區(qū)別在于函數(shù)文本存在于源代碼,而函數(shù)值存在于運(yùn)行期對(duì)象。這個(gè)區(qū)別很像類(lèi)(源代碼)和對(duì)象(運(yùn)行期)的那樣。
以下是對(duì)數(shù)執(zhí)行遞增操作的函數(shù)文本的簡(jiǎn)單例子:
=>指明這個(gè)函數(shù)把左邊的東西(任何整數(shù)x)轉(zhuǎn)變成右邊的東西(x + 1)。所以,這是一個(gè)把任何整數(shù)x映射為x + 1的函數(shù)。
- (x: Int) => x + 1
函數(shù)值是對(duì)象,所以如果你愿意可以把它們存入變量。它們也是函數(shù),所以你可以使用通常的括號(hào)函數(shù)調(diào)用寫(xiě)法調(diào)用它們。以下是這兩種動(dòng)作的例子:
本例中,因?yàn)閕ncrease是var,你可以在之后重新賦給它不同的函數(shù)值。
- scala> var increase = (x: Int) => x + 1
- increase: (Int) => Int = < function>
- scala> increase(10)
- res0: Int = 11
如果你想在函數(shù)文本中包括超過(guò)一個(gè)語(yǔ)句,用大括號(hào)包住函數(shù)體,一行放一個(gè)語(yǔ)句,就組成了一個(gè)代碼塊。與方法一樣,當(dāng)函數(shù)值被調(diào)用時(shí),所有的語(yǔ)句將被執(zhí)行,而函數(shù)的返回值就是***一行產(chǎn)生的那個(gè)表達(dá)式。
- scala> increase = (x: Int) => x + 9999
- increase: (Int) => Int = < function>
- scala> increase(10)
- res2: Int = 10009
于是現(xiàn)在你已經(jīng)看到了有如螺絲和螺帽的函數(shù)文本和函數(shù)值。許多Scala庫(kù)給你使用它們的機(jī)會(huì)。例如,所有的集合類(lèi)都能用到foreach方法。foreach方法被定義在特質(zhì)Iterable中,它是List,Set,Array,還有Map的共有超特質(zhì)。它帶一個(gè)函數(shù)做參數(shù),并對(duì)每個(gè)元素調(diào)用該函數(shù)。下面是如何用它打印輸出所有列表元素的代碼:
- scala> increase = (x: Int) => {
- println("We")
- println("are")
- println("here!")
- x + 1
- }
- increase: (Int) => Int = < function>
- scala> increase(10)
- We
- are
- here!
- res4: Int = 11
另一個(gè)例子是,集合類(lèi)型還有filter方法。這個(gè)方法選擇集合類(lèi)型里可以通過(guò)用戶提供的測(cè)試的元素。測(cè)試是通過(guò)函數(shù)的使用來(lái)提供的。例如,函數(shù)(x: Int) => x > 0可以被用作過(guò)濾。這個(gè)函數(shù)映射正整數(shù)為真,其它為假。下面說(shuō)明如何把它用作filter:
- scala> val someNumbers = List(-11, -10, -5, 0, 5, 10)
- someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)
- scala> someNumbers.foreach((x: Int) => println(x))
- -11
- -10
- -5
- 0
- 5
- 10
- scala> someNumbers.filter((x: Int) => x > 0)
- res6: List[Int] = List(5, 10)
像foreach和filter這樣的方法將在本書(shū)后面描述。
【相關(guān)閱讀】