文章目錄:
上一篇文章帶大家認(rèn)識(shí)到了什么是高階函數(shù),那這一章就帶大家看看高階函數(shù)的實(shí)際使用場(chǎng)景吧
提問(wèn)
我們想一想,高階函數(shù)帶給我們的是什么,我們?yōu)槭裁匆褂盟??因?yàn)樗梢宰屛覀兊姆椒ǜ?jiǎn)單高效,能去掉冗余的樣板代碼,讓我們關(guān)注的邏輯更清晰的展現(xiàn)在我們的面前,所以高階函數(shù)一定是用在我們的方法實(shí)現(xiàn)上,而官方api其實(shí)已經(jīng)將我們常用的快捷操作用高階函數(shù)給封裝好了,比如with,apply等操作符,所以剩下的就是接口調(diào)用了。
不知道大家用Kotlin實(shí)現(xiàn)過(guò)OnClickListener接口沒(méi)有,有3種寫(xiě)法:
青銅版:
view.setOnClickListener(object :View.OnClickListener{
override fun onClick(v: View?) {
//??!我被點(diǎn)擊了
}
})
黃金版
view.setOnClickListener { v ->
{
//??!我被點(diǎn)擊了
}
}
鉆石版
view.setOnClickListener {
//啊!我被點(diǎn)擊了
}
我們一對(duì)比發(fā)現(xiàn),代碼是一步一步被省略的,首先是省略了接口聲明(轉(zhuǎn)化為了lambda),其次是省略了lambda的花括號(hào)(Kotlin的特性,當(dāng)參數(shù)只有一個(gè)lambda參數(shù)的時(shí)候,括號(hào)可以省略),所以我們要實(shí)現(xiàn)的是如何將接口聲明轉(zhuǎn)化為lambda,哈哈,這不正是我們高階函數(shù)所擅長(zhǎng)的嗎
實(shí)現(xiàn)
雖然我們不能直接看到kotlin內(nèi)部的高階函數(shù)的實(shí)現(xiàn)方式,但是我們按住ctrl鍵將鼠標(biāo)移到方法上是可以看到高階函數(shù)的聲明方式的,如你所見(jiàn)是這樣的:
public final fun setOnClickListener( l: ((v: View!) → Unit)! ): Unit
看過(guò)我上篇文章的一眼就能看明白,這是聲明了一個(gè)以view為參數(shù)的無(wú)返回值的高階函數(shù),但他是如何實(shí)現(xiàn)的呢,請(qǐng)看以下代碼:
public final fun setOnClickListener( l: ((v: View!) → Unit)! ): Unit{
//將接口實(shí)現(xiàn)并賦值給全局變量接口方便接口方法調(diào)用
mOnClickListener = object :View.OnClickListener{
override fun onClick(v: View?) {
l.invoke(v) //關(guān)鍵是這句
}
}
}
原理就是內(nèi)部將接口給實(shí)例化,然后將邏輯通過(guò)invoke方法代理出去,這樣我們點(diǎn)擊事件內(nèi)部就會(huì)走invoke方法啦。而invoke實(shí)際是一個(gè)接口(翻譯成java代碼你就明白啦),所以我們?cè)诜椒ㄍ饷鎸?shí)現(xiàn)的其實(shí)是invoke的接口實(shí)現(xiàn)邏輯,注意,這種接口的實(shí)現(xiàn)方式只能在接口只有一個(gè)方法的時(shí)候哦,因?yàn)閕nvoke只有一個(gè),哈哈,怎么樣,setOnClickListener的處理邏輯小伙伴們明白了嗎,舉一反三的事情就交給各位勤奮的小伙伴了.