一、作為值的函數 結果: 二、匿名函數 三、帶函數參數的函數 結果: 四、參數(類型)推斷 匿名函數簡寫: 五、一些有用的高階函數 map這個方法將一個函數應用到某個集合的所有元素並返回結果 foreach將函數應用到每個元素,並不返回結果 結果: filter輸出所有匹配某個特定條件的元素 結果: ...
一、作為值的函數
import scala.math._ val num = 3.14 val func = ceil _ // _意味著確實指的是這個函數,而不是忘記了傳參數 ,func是一個函數變數,內容保存的是個函數 val v = func(num) println(v) val arr = Array(1.0,3.14,4).map(func) //將函數func傳遞給map方法,將他應用到數組中的所有值,然後返回結果數組 for(i<- arr) print(i+" ")
結果:
4.0 1.0 4.0 4.0
二、匿名函數
val func = (x:Double) => x*3 //匿名函數
val arr1 = Array(2.0,4,6).map((x:Double)=> x*3) //匿名函數 val arr2 = Array(2.0,4,6).map{(x:Double)=> x*3} //匿名函數,可以將函數用{}括起來 val arr3 = Array(2.0,4,6) map{(x:Double)=> x*3} //匿名函數,中置表示法,可以不用句號 for(i <- arr1) print(i+" ")
三、帶函數參數的函數
import scala.math._ def valueAtFunc(f: (Double) => Double) = { // f: (Double) => Double 定義函數參數為 double,返回值為double f(0.25) //調用函數的參數為 2.0 } println(valueAtFunc(ceil _)) //將函數傳遞個 函數valueAtFunc println(valueAtFunc(sqrt _))
結果:
1.0 0.5
四、參數(類型)推斷
import scala.math._ def valueAtFunc(f: (Double) => Double) = { // f: (Double) => Double 定義函數參數為 double,返回值為double f(0.25) //調用函數的參數為 2.0 } println(valueAtFunc(ceil _)) //將函數傳遞個 函數valueAtFunc println(valueAtFunc(sqrt _)) valueAtFunc((x:Double) => x*3 ) //匿名函數,指定類型 valueAtFunc((x)=>x*3) //匿名函數,已知參數類型 valueAtFunc(x=>x*3) //匿名函數,已知參數類型,去掉括弧 valueAtFunc(_*3) //使用_替換 x val f1 = 3 * _ //錯誤,沒指定類型 val f2 = 3 *(_:Double) //ok val f3:(Double)=>Double = 3 * _ // ok 指定了f3類型
匿名函數簡寫:
valueAtFunc((x:Double) => x*3 ) //匿名函數,指定類型
valueAtFunc((x)=>x*3) //匿名函數,已知參數類型
valueAtFunc(x=>x*3) //匿名函數,已知參數類型,去掉括弧
valueAtFunc(_*3) //使用_替換 x
五、一些有用的高階函數
map這個方法將一個函數應用到某個集合的所有元素並返回結果
foreach將函數應用到每個元素,並不返回結果
(0 to 9).map("*" * _).foreach(println(_))
結果:
* ** *** **** ***** ****** ******* ******** *********
filter輸出所有匹配某個特定條件的元素
(0 to 9).filter(_ % 2 == 0).foreach(println(_))
結果:
0 2 4 6 8
reduceLeft方法接收一個二元函數,從左到右遍歷元素
println((0 to 9).reduceLeft(_ + _)) // 相當於 (...((((0+1) + 2) + 3) + 4) ...+ 9)
結果
45
sortWith方法二元排序
"I am a bad guy".split(" ").sortWith(_.length<_.length).foreach(println(_))
結果:
I
a
am
bad
guy
六、閉包
閉包由代碼和代碼用到的非局部變數定義構成
七、SAM轉換
Single Abstract Method
八、柯里化
Currying,指的是將原本接收兩個參數的函數變成新的接收一個參數的函數的過程。
def mul(x:Int, y:Int) = x * y //接收兩個參數的函數 def mulOneAtATime(x:Int) = (y:Int)=> x * y //接收一個參數的函數,需要接收兩次參數 def mulOneAtATime1(x:Int)(y:Int) = x * y //柯里化 簡寫 println(mulOneAtATime(3)(4)) println(mulOneAtATime1(3)(4))
柯里化用途:
傳遞一個參數調用函數,有助於對參數類型進行推斷,即類型推斷
val a = Array("Hello","World") val b = Array("hello","world") a.corresponds(b)(_.equalsIgnoreCase(_))
Scaladoc說明
that是String類型的序列,所以第二個函數參數是(String, String) => Boolean,所以適用函數_.equalsIgnoreCase(_)傳遞兩個String類型參數的函數。
九、控制抽象
實現類似while條件控制,柯里化實現
//until函數 類似於while def until(condition: => Boolean) (block: => Unit) { //不帶參數,沒有返回值的函數 block: => Unit if(condition){ block until(condition)(block) } } var x:Int = 10 until(x > 0){ //傳遞兩個函數體, 第一個函數體當做條件,第二個函數體當做計算塊 x -= 1 println(x) }
結果:
9 8 7 6 5 4 3 2 1 0
十、return表達式
//until函數 類似於while def until(condition: => Boolean) (block: => Unit) { //不帶參數,沒有返回值的函數 block: => Unit if(condition){ block until(condition)(block) } } var x:Int = 10 until(x > 0){ //傳遞兩個函數體, 第一個函數體當做條件,第二個函數體當做計算塊 x -= 1 println(x) } def indexOf(str: String, ch:Char): Int ={ var i = 0 until( i!=str.length){ if( str(i) == ch) return i //return 返回給帶名函數,並不返回給匿名函數 {if(str(i) == ch) return i; i+=1}的until i+=1 } return -1 } println(indexOf("Hello", 'i'))
return在控制抽象中很有用。
參考《快學Scala》