介紹Scala的第一類函數
Scala擁有***類函數:first-class function。你不僅可以定義函數和調用它們,還可以把函數寫成沒有名字的文本:literal并把它們像值:value那樣傳遞。我們在第2章介紹了函數文本并在第42頁的圖2.2里展示了基本語法。
51CTO編輯推薦:Scala編程語言專題
函數文本被編譯進一個類,類在運行期實例化的時候是一個函數值:function value。任何函數值都是某個擴展了若干scala包的FunctionN特質之一的類的實例,如Function0是沒有參數的函數,Function1是有一個參數的函數等等。每個FunctionN特質有一個apply方法用來調用函數。因此函數文本和值的區別在于函數文本存在于源代碼,而函數值存在于運行期對象。這個區別很像類(源代碼)和對象(運行期)的那樣。
以下是對數執行遞增操作的函數文本的簡單例子:
=>指明這個函數把左邊的東西(任何整數x)轉變成右邊的東西(x + 1)。所以,這是一個把任何整數x映射為x + 1的函數。
- (x: Int) => x + 1
函數值是對象,所以如果你愿意可以把它們存入變量。它們也是函數,所以你可以使用通常的括號函數調用寫法調用它們。以下是這兩種動作的例子:
本例中,因為increase是var,你可以在之后重新賦給它不同的函數值。
- scala> var increase = (x: Int) => x + 1
- increase: (Int) => Int = < function>
- scala> increase(10)
- res0: Int = 11
如果你想在函數文本中包括超過一個語句,用大括號包住函數體,一行放一個語句,就組成了一個代碼塊。與方法一樣,當函數值被調用時,所有的語句將被執行,而函數的返回值就是***一行產生的那個表達式。
- scala> increase = (x: Int) => x + 9999
- increase: (Int) => Int = < function>
- scala> increase(10)
- res2: Int = 10009
于是現在你已經看到了有如螺絲和螺帽的函數文本和函數值。許多Scala庫給你使用它們的機會。例如,所有的集合類都能用到foreach方法。foreach方法被定義在特質Iterable中,它是List,Set,Array,還有Map的共有超特質。它帶一個函數做參數,并對每個元素調用該函數。下面是如何用它打印輸出所有列表元素的代碼:
- 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
另一個例子是,集合類型還有filter方法。這個方法選擇集合類型里可以通過用戶提供的測試的元素。測試是通過函數的使用來提供的。例如,函數(x: Int) => x > 0可以被用作過濾。這個函數映射正整數為真,其它為假。下面說明如何把它用作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這樣的方法將在本書后面描述。
【相關閱讀】



















