首發(fā)于公眾號: DSGtalk1989
19.高階函數(shù)與 lambda 表達式
我們通常將函數(shù)作為參數(shù)或者返回值的函數(shù)成為高階函數(shù)
-
帶接收者的函數(shù)類型
在kotlin中我們,函數(shù)也是一種類型。比如
() -> Int,這個表示無參的返回類型為整型的函數(shù)。(String, Int) -> Int表示需要兩個參數(shù)String和Int,并且返回的Int的函數(shù)。這里要介紹的是帶接收者的函數(shù)類型,比如
String.(String) -> Int,其實也是需要兩個參數(shù),但是這樣表達的好處是這個方法可以被當做拓展函數(shù)來使用。val stringPlus: String.(String) -> String = String::plus fun main() { stringPlus("1", "2") "1".stringPlus("2") }我們即可以直接傳兩個
String到這個方法中去,也可以當成拓展函數(shù)來直接調(diào)用String的stringPlus方法,并且往里面?zhèn)饕粋€字符串。也就是
String.(String)可以當成(String,String)來使用,而反過來則不行哦。
-
invoke方法
invoke關(guān)鍵字跟在方法名后面,表示調(diào)用該方法,跟不加的效果是一樣的,同上的例子println(stringPlus.invoke("<-", "->")) println(stringPlus("Hello, ", "world!"))invoke關(guān)鍵字還會用在類或者接口內(nèi)的方法定義中class AA { companion object Factory { operator fun invoke (xxx: Any) = xxx fun test11(){} } operator fun invoke(dda : String) = "22" fun test(){ } }我們在兩個地方使用到了
invoke,注意,我們直接通過操作符重載的方式可以定義類本身的構(gòu)造方法。比如上面的伴生對象的
invoke方法,就是重載了伴生對象的構(gòu)造方法,即直接調(diào)用AA(xxx: Any)可以獲得一個Any對象。或者我們走一個更加容易理解的方式,就是所有重載的
invoke操作符,我們都可以通過對象.invoke(參數(shù))的方式去調(diào)用,由于invoke又是可以省略的,所以我們可以直接通過對象(參數(shù))的方式去調(diào)用//伴生對象(參數(shù))直接使用 val aaa: Any = AA(6) val aa: Unit = AA.test11() val bbb = AA() bbb.test() bbb.invoke("1") //對象(參數(shù)) bbb("1")
-
lambda中it的出現(xiàn)時機
我們在前面講過,通常高階函數(shù)的定義和調(diào)用方式如下
fun html( a : (String, Int, Short) -> String){ } html { s, i, sh -> "test" }由于高階函數(shù)最后一個參數(shù)是函數(shù),所以可以直接寫在方法外,又由于只有一個函數(shù)參數(shù),所以連括號都可以省去了。
其次,我們傳入函數(shù)的方式是,大括號,并且包括所有的參數(shù)自定義(一般為類型的大寫字母,比如
String就是s,Int就是i,Short就是sh)加上->然后是函數(shù)體。kotlin中將高階函數(shù)中的函數(shù)參數(shù)只有一個傳參的情況簡略了我們自己去寫
s ->的過程,直接幫我們生成了it ->,即fun html( a : (String) -> String){ } html { s -> s + "test" } //等價 html { it + "test" }
-
函數(shù)參數(shù)的自動識別
kotlin可以自動進行推斷函數(shù)體,比如,我們需要傳入高階函數(shù)的函數(shù)體是
(Int) -> Int,那么如果有什么方法本身也是這種類型的,直接傳入改方法即可。fun html( a : (String) -> String){ } fun testString(a : String): String{ return a } fun main(){ html { testString("1") } } -
高階函數(shù)沒有使用到函數(shù)參數(shù)
我們上面舉的例子中都沒有使用到具體的方法參數(shù),即
html中我們并沒有去使用a,這樣的話在編譯的過程中,傳入的方法將不會被編譯。即上文中的
testString方法將完全不會被編譯到main方法中高階函數(shù)我們一般的使用方法都是在方法中調(diào)用方法,直接調(diào)用方法的方式如下
fun html( a : (String) -> String){ a.invoke("hello") a("hello") }否則高階函數(shù)將變得沒有意義。
Kotlin學(xué)習(xí)筆記之 1 基礎(chǔ)語法
Kotlin學(xué)習(xí)筆記之 2 基本數(shù)據(jù)類型
Kotlin學(xué)習(xí)筆記之 4 循環(huán)控制
Kotlin學(xué)習(xí)筆記之 9 數(shù)據(jù)類與密封類
Kotlin學(xué)習(xí)筆記之 12 對象表達式和對象聲明
Kotlin學(xué)習(xí)筆記之 13 基礎(chǔ)操作符run、with、let、also、apply
Kotlin學(xué)習(xí)筆記之 14 包與導(dǎo)入
Kotlin學(xué)習(xí)筆記之 18 函數(shù)
Kotlin學(xué)習(xí)筆記之 19 高階函數(shù)與 lambda 表達式
Kotlin學(xué)習(xí)筆記之 20 內(nèi)聯(lián)函數(shù)
Kotlin學(xué)習(xí)筆記之 21 解構(gòu)聲明
Kotlin學(xué)習(xí)筆記之 28 協(xié)程基礎(chǔ)
Kotlin學(xué)習(xí)筆記之 29 上下文與調(diào)度器
Kotlin學(xué)習(xí)筆記之 30 協(xié)程取消與超時
Kotlin學(xué)習(xí)筆記之 31 協(xié)程掛起函數(shù)的組合