這篇文章將為大家詳細(xì)講解有關(guān)Kotlin中內(nèi)聯(lián)函數(shù)的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
內(nèi)聯(lián)函數(shù)的理解
inline函數(shù)(內(nèi)聯(lián)函數(shù))從概念上講是編譯器使用函數(shù)實(shí)現(xiàn)的真實(shí)代碼來(lái)替換每一次的函數(shù)調(diào)用,帶來(lái)的最直接的好處就是節(jié)省了函數(shù)調(diào)用的開銷,而缺點(diǎn)就是增加了所生成字節(jié)碼的尺寸?;诖?,在代碼量不是很大的情況下,我們是否有必要將所有的函數(shù)定義為內(nèi)聯(lián)?讓我們分兩種情況進(jìn)行說(shuō)明:
將普通函數(shù)定義為內(nèi)聯(lián):眾所周知,JVM內(nèi)部已經(jīng)實(shí)現(xiàn)了內(nèi)聯(lián)優(yōu)化,它會(huì)在任何可以通過(guò)內(nèi)聯(lián)來(lái)提升性能的地方將函數(shù)調(diào)用內(nèi)聯(lián)化,并且相對(duì)于手動(dòng)將普通函數(shù)定義為內(nèi)聯(lián),通過(guò)JVM內(nèi)聯(lián)優(yōu)化所生成的字節(jié)碼,每個(gè)函數(shù)的實(shí)現(xiàn)只會(huì)出現(xiàn)一次,這樣在保證減少運(yùn)行時(shí)開銷的同時(shí),也沒(méi)有增加字節(jié)碼的尺寸;所以我們可以得出結(jié)論,對(duì)于普通函數(shù),我們沒(méi)有必要將其聲明為內(nèi)聯(lián)函數(shù),而是交給JVM自行優(yōu)化。
將帶有l(wèi)ambda參數(shù)的函數(shù)定義為內(nèi)聯(lián):是的,這種情況下確實(shí)可以提高性能;但在使用的過(guò)程中,我們會(huì)發(fā)現(xiàn)它是有諸多限制的,讓我們從下面的例子開始展開說(shuō)明:
inline fun doSomething(action: () -> Unit) { println("Before doSomething...") action() println("After doSomething...") }
假如我們這樣調(diào)用doSomething:
fun main(args: Array<String>) { doSomething { pringln("Hello World") } }
上面的調(diào)用會(huì)被編譯成:
fun main(args: Array<String>) { println("Before doSomething...") println("Hello World") println("After doSomething...") }
從上面編譯的結(jié)果可以看出,無(wú)論doSomething函數(shù)還是action參數(shù)都被內(nèi)聯(lián)了,很棒,那讓我們換一種調(diào)用方式:
fun main(args: Array<String>) { val action:() -> Unit = { println("Hello World") } doSomething(action) }
上面的調(diào)用會(huì)被編譯成:
fun main(args: Array<String>) { println("Before doSomething...") action() println("After doSomething...") }
doSomething函數(shù)被內(nèi)聯(lián),而action參數(shù)沒(méi)有被內(nèi)聯(lián),這是因?yàn)橐院瘮?shù)型變量的形式傳遞給doSomething的lambda在函數(shù)的調(diào)用點(diǎn)是不可用的,只有等到doSomething被內(nèi)聯(lián)后,該lambda才可以正常使用。
通過(guò)上面的例子,我們對(duì)lambda表達(dá)式何時(shí)被內(nèi)聯(lián)做一下簡(jiǎn)單的總結(jié):
當(dāng)lambda表達(dá)式以參數(shù)的形式直接傳遞給內(nèi)聯(lián)函數(shù),那么lambda表達(dá)式的代碼會(huì)被直接替換到最終生成的代碼中。
當(dāng)lambda表達(dá)式在某個(gè)地方被保存起來(lái),然后以變量形式傳遞給內(nèi)聯(lián)函數(shù),那么此時(shí)的lambda表達(dá)式的代碼將不會(huì)被內(nèi)聯(lián)。
上面對(duì)lambda的內(nèi)聯(lián)時(shí)機(jī)進(jìn)行了討論,消化片刻后讓我們?cè)倏醋詈笠粋€(gè)例子:
inline fun doSomething(action: () -> Unit, secretAction: () -> Unit) { action() doSomethingSecret(secretAction) } fun doSomethingSecret(secretAction: () -> Unit) { }
上面的例子是否有問(wèn)題?是的,編譯器會(huì)拋出“Illegal usage of inline-parameter”的錯(cuò)誤,這是因?yàn)镵otlin規(guī)定內(nèi)聯(lián)函數(shù)中的lambda參數(shù)只能被直接調(diào)用或者傳遞給另外一個(gè)內(nèi)聯(lián)函數(shù),除此之外不能作為他用;那我們?nèi)绻_實(shí)想要將某一個(gè)lambda傳遞給一個(gè)非內(nèi)聯(lián)函數(shù)怎么辦?我們只需將上述代碼這樣改造即可:
inline fun doSomething(action: () -> Unit, noinline secretAction: () -> Unit) { action() doSomethingSecret(secretAction) } fun doSomethingSecret(secretAction: () -> Unit) { }
很簡(jiǎn)單,在不需要內(nèi)聯(lián)的lambda參數(shù)前加上noinline修飾符就可以了。
以上便是我對(duì)內(nèi)聯(lián)函數(shù)的全部理解,通過(guò)掌握該特性的運(yùn)行機(jī)制,相信大家可以做到在正確的時(shí)機(jī)使用該特性,而非濫用或因恐懼棄而不用。
關(guān)于“Kotlin中內(nèi)聯(lián)函數(shù)的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
當(dāng)前名稱:Kotlin中內(nèi)聯(lián)函數(shù)的示例分析-創(chuàng)新互聯(lián)
鏈接URL:http://jinyejixie.com/article30/ccespo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、域名注冊(cè)、網(wǎng)站導(dǎo)航、手機(jī)網(wǎng)站建設(shè)、面包屑導(dǎo)航、全網(wǎng)營(yíng)銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)