2021年大数据常用语言Scala(三十七):scala高级用法 高阶函数用法
目錄
高階函數用法
作為值的函數
匿名函數
柯里化(多參數列表)
閉包
高階函數用法
Scala 混合了面向對象和函數式的特性,在函數式編程語言中,函數是“頭等公民”,它和Int、String、Class等其他類型處于同等的地位,可以像其他任何數據類型一樣被傳遞和操作。
高階函數包含:作為值的函數、匿名函數、閉包、柯里化等等。
?
作為值的函數
在scala中,函數就像和數字、字符串一樣,可以將函數傳遞給一個方法。我們可以對算法進行封裝,然后將具體的動作傳遞給算法,這種特性很有用。
我們之前學習過List的map方法,它就可以接收一個函數,完成List的轉換。
示例:將一個小數列表中的每個元素轉換為對應個數的小星星
List(1, 2, 3...) => *, \, \?
代碼:
val?list =?List(1,?2,?3,?4)// 字符串*方法,表示生成指定數量的字符串
val?func_num2star =?(num:Int)?=>?"*"?*?numprint(list.map(func_num2star))
?
匿名函數
上面的代碼,給(num:Int) => "*" * num函數賦值給了一個變量,但是這種寫法有一些啰嗦。在scala中,可以不需要給函數賦值給變量,沒有賦值給變量的函數就是匿名函數
示例:優化上述代碼
val?list =?List(1,?2,?3,?4)list.map(num =>?"*"?*?num).foreach(println)
// 因為此處num變量只使用了一次,而且只是進行簡單的計算,所以可以省略參數列表,使用_替代參數
list.map("*"?*?_).foreach(println)
?
柯里化(多參數列表)
list.fold(100)(_ + _)
柯里化(Currying)允許方法接收多個參數列表的語法特性。
多數用于隱式轉換或者在邏輯上劃分不同批次的參數用。
特點:參數如果不傳遞完全,得到一個函數
?
柯里化過程解析
使用柯里化,讓傳遞匿名函數作為參數的語法更為簡潔
示例:編寫一個泛型方法,用來完成兩個值類型的計算(具體的計算封裝到函數中)
object?CurryingDemo2 {// 實現對兩個數進行計算的方法def?calc[A <:?AnyVal](x:A,?y:A,?func_calc:(A,?A)=>A)?=?{func_calc(x,?y)}// 柯里化:實現對兩個數進行計算def?calc_carried[A <:?AnyVal](x:A,?y:A)(func_calc:(A,?A)=>A)?=?{func_calc(x,?y)}def?main(args:?Array[String]):?Unit?=?{// 這種寫法是不能被簡化的,必須要寫出函數的定義println(calc(10,?10,?(x:Int,?y:Int)=>?x +?y))println(calc(10.1,?10.2,?(x:Double,?y:Double)=>?x*y))// 柯里化之后可以快樂地使用下劃線了println(calc_carried(10,?10)(_ +?_))println(calc_carried(10.1,?10.2)(_ *?_))println(calc_carried(100.2,?10)(_ -?_))}
}
?
閉包
閉包其實就是一個函數,只不過這個函數的返回值依賴于聲明在函數外部的變量。
可以簡單認為,就是可以訪問不在當前作用域范圍的一個函數。
可以不修改方法體,通過外部變量來控制方法返回結果
示例:定義一個閉包
object?ClosureDemo {def?add(x:Int)?=?{val?y =?10// add返回一個函數,該函數引用了add方法的一個局部變量val?funcAdd =?()?=>?x +?yfuncAdd}def?main(args:?Array[String]):?Unit?=?{// 調用add方法時,任然可以引用到y的值// funcAdd函數就是一個閉包println(add(10)())}
}
?
上面的演示只是使用一個普通的int值來做的閉包。 如果依賴的外部變量是一個函數呢?
?
那就是,無需修改方法體, 修改外部函數就能修改計算邏輯。
總結
以上是生活随笔為你收集整理的2021年大数据常用语言Scala(三十七):scala高级用法 高阶函数用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021年大数据常用语言Scala(三十
- 下一篇: 2021年大数据常用语言Scala(三十