前言 :
Scala 是一個可直譯、編譯、靜態、運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. Scala 本身具有擴充性,不過這必須了解更多語法特性與細節.
閉包(Closure) :
所謂的閉包(Closure),是指一個函式物件(或函式值)在建立時,綁定了當時作用範圍(Scope)下有效的自由變數(Free variable)。所 以支援閉包的語言,必須有支援一級函式(First-class function),建立函式物件並不等於建立閉包,建立函式物件時同時綁定了某個([color=brown]些)自由變數,該函式物件才稱之為閉包[/color]. 那麼什麼是自由變數?自由變數是指對於函式而言,既非區域變數也非參數的變數,像區域變數或參數,其作用範圍基本上是在函式定義的範 圍中,所以是有界變數(Bound variable)。舉個例子來說 :
上面 doSome 的例子中,(y: Int) => x + y 形成了一個閉包,如果你單看 :
- val f = (y: Int) => x + y
- val foo = doSome()
- println(foo(20)) // 顯示 30
- println(foo(30)) // 顯示 40
在建立閉包時,綁定了 x 變數,而不是數值 10(x 變數的值),也因此 doOther 之後改變了 x 變數的值,而後傳回閉包給 foo 參數後,範例顯示的結果分別是 100+20 與 100+30。由於閉包綁定的是變數,所以你也可以在閉包中改變了變數值 :
- var sum = 0
- val arr = Array(1, 2, 3, 4, 5)
- arr.foreach(sum += _)
- println(sum) // 顯示 15
- def doOther() = {
- var x = 10
- val f = () => { x -= 1; x }
- f
- }
- val f1 = doOther()
- val f2 = doOther()
- println(f1()) // 顯示 9
- println(f2()) // 顯示?
雖然沒有指出,不過上一個主題 一級函式(First-class function) 的最後一個範例,已經應用了閉包來解決問題.
沒有留言:
張貼留言