Scala學習筆記4--函數值

Scala函數值


函數值的使用

  1. 可以在函數裏創建函數
  2. 將函數賦給引用
  3. 當作參數傳給其他函數
  4. 作爲函數的返回值

單參函數值

def totalResultOverRange(number: Int, codeBlock: Int => Int) : Int = {  
    var result = 0  
    for (i <- 1 to number) {    
        result += codeBlock(i)  
    }  
    result
}
println(totalResultOverRange(11, i => i))
println(totalResultOverRange(11, i => if (i%2 == 0)1 else 0))
println(totalResultOverRange(11, i => if (i%2 != 0)1 else 0))

多參函數值

def inject(arr: Array[Int], initial: Int, operation: (Int, Int) => Int) : Int = {
    var carryOver = initial  
    arr.foreach( element => carryOver = operation(carryOver, element) )  
    carryOver
}
val array = Array(2, 3, 5, 1, 6, 4)
val sum = inject(array, 0, (carryOver, elem) => carryOver + elem)
val max = inject(array, Integer.MIN_VALUE,   (carryOver, elem) => Math.max(carryOver, elem)  )

operation: (Int, Int) => Int : Int表示函數名、參數類型和返回值類型(函數值的申明)
這裏的operation函數中有一個賦值操作,賦值對象爲carryOver

Curry化

curry化可以把函數從接收多個參數轉換成接收多個參數列表。
def foo(a: Int, b: Int, c: Int) {}可以改寫成def foo(a: Int)(b: Int)(c: Int) {}形式。
對應的調用方法爲foo(1)(2)(3)、foo(1){2}{3},甚至foo{1}{2}{3}。

def inject(arr: Array[Int], initial: Int)(operation: (Int, Int) => Int) : Int = {  
    var carryOver = initial  
    arr.foreach(element => carryOver = operation(carryOver, element))  
    carryOver
}

爲函數值創建引用

  • 函數值的引用
val calculator = { input : Int => println("calc with " + input); input }

input : Int表示函數值的參數名和參數類型(函數值的實現)

  • 定義函數
def calculator(input: Int) = { println("calc with " + input); input }

位置參數簡化

  • 簡化一個參數
val negativeNumberExists = arr.exists { _ < 0 }
  • 簡化兩個參數
(0 /: arr) { (sum, elem) => sum + elem }
(0 /: arr) { _+_}

def max2(a: Int, b: Int) : Int = if (a> b)a else b
(Integer.MIN_VALUE /: arr) { (large, elem) => max2(large, elem) }
(Integer.MIN_VALUE /: arr) { max2(_, _) }

第一個出現的_表示的是一個函數調用過程中持續存在的值,第二個表示數組元素

  • 簡化整個參數列表
max = (Integer.MIN_VALUE /: arr) { max2 _ }
  • 簡化爲零
max = (Integer.MIN_VALUE /: arr) { max2 }

借貸模式

import java.io._
def writeToFile(fileName: String)(codeBlock : PrintWriter => Unit) = {
    val writer = new PrintWriter(new File(fileName))//借  
    try { 
        codeBlock(writer)//使用 
    } finally { 
        writer.close()//還
    }
}
writeToFile("output.txt") { writer =>  writer write "hello from Scala" }

偏應用函數

一個函數如果只傳遞幾個參數其它的留待後面填寫,就得到了一個偏應用函數。使用_指定不綁定的參數

def log(date: Date, message: String) 
val logWithDateBound = log(new Date, _ : String)

閉包

如果代碼塊包含未綁定的參數就稱爲閉包,調用函數之前必須綁定這些參數。

  • 函數值引用綁定
def loopThrough(number: Int)(closure: Int => Unit) {        
    for (i <- 1 to number) { closure(i) }
}
var result = 0
val addIt = { value:Int => result += value }
loopThrough(10) { addIt }
  • 匿名函數綁定
var product = 1
loopThrough(5) { product *=_ }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章