十一、高階函數
scala的函數對象是一種特殊的class,即可擔當函數計算職責又可以作爲變量傳遞
作爲值的函數
object Function04 {
def main(args: Array[String]): Unit = {
val result = sum _ // _ 匹配函數參數列表
println(result)
}
def sum(x: Int, y: Int): Int = x + y
}
作用:
- 調用
- 作爲參數傳遞
匿名函數(略)
參考之前
柯里化函數(略)
帶函數參數的函數
object Function05 {
def main(args: Array[String]): Unit = {
val f1 = (x: Int, y: Int) => x + y // 聲明匿名函數
val result = sum(1, 2, f1)
println(result) // 3
}
def sum(x: Int, y: Int, f: (Int, Int) => Int) = { // 帶函數參數的函數 函數作爲值傳遞
f(x, y)
}
}
參數(類型)推斷
// 方式1
val a1 = Array(1, 2, 3, 4)
val f2 = (x: Int) => println(x)
// foreach 遍歷方法 參數需要一個函數對象
a1.foreach(f2)
// 方式2
a1.foreach((x) => println(x)) // 函數參數的類型自動推導
// 方式3
a1.foreach(x => println(x)) // 對於只有一個參數的函數,省略參數外圍的()
// 方式4
a1.foreach(println(_)) // 參數在 => 右側出現一次,可以用 _ 替換掉
// 方式5
a1.foreach(println) // 更爲簡化的寫法
一些有用的高階函數
-
map 映射方法
Array(1, 2, 3, 4, 5).map("*" * _).foreach(println _)
-
filter 過濾方法
(1 to 10).filter(_ % 2 == 0).foreach(println)
-
reduceLeft 從左計算
(1 to 10).filter(_ % 2 == 0).reduceLeft((x,y) => x+y) // 30
-
WordCount(單詞計數)
val a1 = Array("Hello Scala", "Hello Hadoop", "Hello Hello Hello") a1.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).map(x => (x._1, x._2.length)).foreach(println)
函數閉包
閉包指在函數體內,可以訪問相應作用域內的任何變量,因爲它引用到函數外面定義的變量,定義這個函數的過程是將這個自由變量捕獲而構成一個封閉的函數。
語法:函數 + 外部變量 = 閉包
如:
var num = 1 // 外部變量
val result = (x: Int) => num + x // 匿名函數引用外部變量,閉包後 多次調用 共享相同的外部變量
println(result(1)) // 1
num += 10
println(result(1)) // 12
// f1 按道理來說 函數對象不能夠使用當前類的聲明變量
// 函數閉包:可以將當前外部變量 閉包到函數對象中 語法: 函數對象 + 外部變量 = 閉包
// 外部變量是一個共享變量,一旦外部變量值發生變化 會影響到函數對象中的內容