內(nèi)聯(lián)函數(shù)關(guān)鍵字
1.inline
2.noinline
3.crossinline
inline 是Kotlin 修飾方法的關(guān)鍵字。
noinline 挽荡,crossinline 是配合帶有inline 方法修飾參數(shù)的關(guān)鍵字入录。
用法 并且 分析
inline
內(nèi)聯(lián)函數(shù)寫(xiě)法
內(nèi)聯(lián)函數(shù)相當(dāng)于在該函數(shù)內(nèi)权逗,在調(diào)用另一個(gè)函數(shù)越庇,某些需要開(kāi)發(fā)者自己實(shí)現(xiàn)的功能它褪,我只需傳入固定好的參數(shù),可根據(jù)需求定義返回值陶贼。
在sun函數(shù)前后處理一些固定的邏輯處理。
inline fun addUp(a: Int, b: Int, sum: (sum: Int) -> Unit) {
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行前待秃。")
sum(a + b)
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行后拜秧。")
}
Java 調(diào)用內(nèi)聯(lián)函數(shù)寫(xiě)法
方法中最后一個(gè)參數(shù)就是平常寫(xiě)的回調(diào)。
Function1 第一個(gè)泛型是傳入的參數(shù)類(lèi)型章郁,第二個(gè)是返回值類(lèi)型枉氮。Kolitn 中 Unit 等同于Java void。
如果參數(shù)是多個(gè) Function1 - Function21 針對(duì)參數(shù)個(gè)數(shù)自行創(chuàng)建暖庄。
如果超過(guò)21一個(gè)參數(shù)聊替,那你就要考慮自己的方法是不是定義的有問(wèn)題了,可拆分培廓,Kotlin 中支持多個(gè)代碼塊參數(shù)惹悄。
結(jié)論 inline 在Java用法等同于Java 的回調(diào)。
TestInLineKt.addUp(10, 20, new Function1<Integer, Unit>() {
@Override
public Unit invoke(Integer integer) {
System.out.println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行結(jié)果肩钠。$it");
return null;
}
});
Kotlin 調(diào)用內(nèi)聯(lián)函數(shù)
調(diào)用方法泣港,最后一個(gè)參數(shù)如果是代碼塊參數(shù)暂殖,可以寫(xiě)在小括號(hào)外面。
fun main(args: Array<String>) {
val a = 10
valb = 20
addUp(a, b) {
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行結(jié)果当纱。$it")
}
}
noinline
ps:內(nèi)聯(lián)函數(shù)在字節(jié)碼中會(huì)進(jìn)行優(yōu)化呛每,將整個(gè)內(nèi)聯(lián)函數(shù)全部放到調(diào)用地方,等同于沒(méi)有調(diào)用方法坡氯,在運(yùn)行過(guò)程中減少了入棧出棧的過(guò)程晨横。
等同于寫(xiě)法
fun main(args: Array<String>) {
val a = 10
val b = 20
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行前。")
var sum = a + b
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行結(jié)果箫柳。$sum")
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行后手形。")
}
上面案例只寫(xiě)了內(nèi)聯(lián)函數(shù)中只包含一個(gè)代碼塊參數(shù)。
如果需要將內(nèi)聯(lián)代碼塊滞时,傳遞個(gè)另一個(gè)沒(méi)有 inline 修飾的方法將會(huì)提示錯(cuò)誤叁幢。
需要添加 noinline 參數(shù)修飾,也就意味著這個(gè)參數(shù)將不會(huì)被編譯成字節(jié)碼的時(shí)候優(yōu)化坪稽。
inline fun addUp(a: Int, b: Int, noinline sum: (sum: Int) -> Unit) {
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行前曼玩。")
check(sum)
println("內(nèi)聯(lián)函數(shù) sum 執(zhí)行后。")
}
fun check(sum: (i: Int) -> Unit) {
println("另一個(gè)內(nèi)聯(lián)函數(shù)窒百。")
sum(20)
}
crossinline
在代碼中任何位置都可以寫(xiě) return 關(guān)鍵字黍判,但是在內(nèi)聯(lián)函數(shù)中經(jīng)過(guò)jvm優(yōu)化整個(gè)方法會(huì)被復(fù)制到調(diào)用的地方包括return,這就造成了下面方法無(wú)法運(yùn)行篙梢。
在addUp代碼塊中添加 return 關(guān)鍵字運(yùn)行顷帖。
fun main(args: Array<String>) {
val a = 10
val b = 20
println("調(diào)用內(nèi)聯(lián)函數(shù)執(zhí)行前。")
addUp(a, b) {
println("內(nèi)聯(lián)方法 sum 執(zhí)行結(jié)果渤滞。$it")
return
}
println("調(diào)用內(nèi)聯(lián)函數(shù)執(zhí)行后贬墩。")
}
inline fun addUp(a: Int, b: Int, sum: (sum: Int) -> Unit) {
println("內(nèi)聯(lián)方法 sum 執(zhí)行前。")
sum(a + b)
println("內(nèi)聯(lián)方法 sum 執(zhí)行后妄呕。")
}
打印結(jié)果:沒(méi)有打印 “內(nèi)聯(lián)方法 sum 執(zhí)行后陶舞。” 和 “調(diào)用內(nèi)聯(lián)函數(shù)執(zhí)行后绪励≈追酰” 代碼方法在之前被終止。
調(diào)用內(nèi)聯(lián)函數(shù)執(zhí)行前疏魏。
內(nèi)聯(lián)方法 sum 執(zhí)行前停做。
內(nèi)聯(lián)方法 sum 執(zhí)行結(jié)果。30
Process finished with exit code 0
解決辦法
一. 指定 return 退出哪個(gè)函數(shù)大莫。@ 后面跟內(nèi)聯(lián)函數(shù)的名稱(chēng)
return@addUp
二.在方法一中蛉腌,如不指定 return 出哪個(gè)函數(shù)不會(huì)有語(yǔ)法檢測(cè),當(dāng)在內(nèi)聯(lián)函數(shù)中添加 crossinline 關(guān)鍵字后,return 后面會(huì)強(qiáng)制指定退出當(dāng)前內(nèi)聯(lián)函數(shù)眉抬。
fun main(args: Array<String>) {
val a = 10
val b = 20
println("調(diào)用內(nèi)聯(lián)函數(shù)執(zhí)行前贯吓。")
addUp(a, b) {
println("內(nèi)聯(lián)方法 sum 執(zhí)行結(jié)果。$it")
return@addUp
}
println("調(diào)用內(nèi)聯(lián)函數(shù)執(zhí)行后蜀变。")
}
inline fun addUp(a: Int, b: Int, crossinline sum: (sum: Int) -> Unit) {
println("內(nèi)聯(lián)方法 sum 執(zhí)行前悄谐。")
sum(a + b)
println("內(nèi)聯(lián)方法 sum 執(zhí)行后。")
}