Scala 高階函式
1.作為引數的函式
函式作為一個變數傳入到了另一個函式中,那麼該作為引數的函式的型別是:function1,即:(引數型別) => 返回型別
def plus(x: Int) = 3 + x
val result1 = Array(1, 2, 3, 4).map(plus(_))
println(result1.mkString(“-"))
注:帶有一個引數的函式的型別是function1,帶有兩個是function2,以此類推
2.匿名函式
即沒有名字的函式,可以通過函式表示式來設定匿名函式。
//即沒有名字的函式,可以通過函式表示式來設定匿名函式。 val triple = (x: Int) => 3 * x println(triple(3))
3.高階函式
能夠接受函式作為引數的函式,叫做高階函式。
//能夠接受函式作為引數的函式,叫做高階函式。 // (1)高階函式的使用 def highOrderFunction1(f: Double => Double) = f(10) def minus7(x: Double) = x - 7 val result2 = highOrderFunction1(minus7) println(result2) // (2)高階函式同樣可以返回函式型別 def minusxy(x: Int) = (y: Int) => x - y val result3 = minusxy(3)(5) println(result3)
4.引數(型別)推斷
// 傳入函式表示式
highOrderFunction1((x: Double) => 3 * x)
// 引數推斷省去型別資訊
highOrderFunction1((x) => 3 * x)
// 單個引數可以省去括號
highOrderFunction1(x => 3 * x)
// 如果變數旨在=>右邊只出現一次,可以用_來代替
highOrderFunction1(3 * _)
5. 閉包
閉包就是一個函式把外部的那些不屬於自己的物件也包含(閉合)進來。
def minusxy(x: Int) = (y: Int) => x - y
這就是一個閉包:
(1)匿名函式(y: Int) => x -y巢狀在minusxy函式中。
(2)匿名函式(y: Int) => x -y使用了該匿名函式之外的變數x
(3)函式minusxy返回了引用了局部變數的匿名函式
再舉一例:
def minusxy(x: Int) = (y: Int) => x - y
val f1 = minusxy(10)
val f2 = minusxy(10)
println(f1(3) + f2(3))
此處f1,f2這兩個函式就叫閉包。
6.柯里化
函式程式設計中,接受多個引數的函式都可以轉化為接受單個引數的函式,這個轉化過程就叫柯里化,柯里化就是證明了函式只需要一個引數而已。其實我們剛才的學習過程中,已經涉及到了柯里化操作,所以這也印證了,柯里化就是以函式為主體這種思想發展的必然產生的結果。
(1)柯里化示例
def mul(x: Int, y: Int) = x * y
println(mul(10, 10))
def mulCurry(x: Int) = (y: Int) => x * y
println(mulCurry(10)(9))
def mulCurry2(x: Int)(y:Int) = x * y
println(mulCurry2(10)(8))
(2)柯里化的應用
比較兩個字串在忽略大小寫的情況下是否相等,注意,這裡是兩個任務:
① 全部轉大寫(或小寫)
② 比較是否相等
針對這兩個操作,我們用一個函式去處理的思想,其實無意間也變成了兩個函式處理的思想。示例如下:
val a = Array("Hello", "World")
val b = Array("hello", "world")
println(a.corresponds(b)(_.equalsIgnoreCase(_)))
其中corresponds函式的原始碼如下:
def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Boolean = {
val i = this.iterator
val j = that.iterator
while (i.hasNext && j.hasNext)
if (!p(i.next(), j.next()))
return false
!i.hasNext && !j.hasNext
}
注:不要設立柯里化存在的意義這樣的命題,柯里化,是面向函式思想的必然產生結果。
7.控制抽象
控制抽象是一類函式:
引數是函式。
函式引數沒有輸入值也沒有返回值。
(1)使用示例
def runInThread(f1: () => Unit): Unit = {
new Thread {
override def run(): Unit = {
f1()
}
}.start()
}
runInThread {
() => println("幹活咯!")
Thread.sleep(5000)
println("幹完咯!")
}
是不是很爽?是不是有點類似執行緒池的感覺,同一個執行緒,可以動態的向裡面塞不同的任務去執行。可以再簡化一下,省略(),看下如下形式:
def runInThread(f1: => Unit): Unit = {
new Thread {
override def run(): Unit = {
f1
}
}.start()
}
runInThread {
println("幹活咯!")
Thread.sleep(5000)
println("幹完咯!")
}
(2)進階用法:實現類似while的until函式
def until(condition: => Boolean)(block: => Unit) {
if (!condition) {
block
until(condition)(block)
}
}
var x = 10
until(x == 0) {
x -= 1
println(x)
}