kotlin中有個(gè)關(guān)鍵字inline康愤,被它修飾的函數(shù)稱為內(nèi)聯(lián)函數(shù)半开。那么我們來分析下它鉴未。
1.inline的作用枢冤?
當(dāng)一個(gè)函數(shù)被inline標(biāo)注后,在編譯時(shí)期铜秆,把調(diào)用這個(gè)函數(shù)的地方用這個(gè)函數(shù)的方法體進(jìn)行替換淹真。簡(jiǎn)而言之,就是說直接把代碼復(fù)制過去一份连茧,不通過方法間壓棧進(jìn)棧的方式進(jìn)行調(diào)用核蘸。
2.inline的使用
根據(jù)官方推薦的規(guī)則:
1.不帶參數(shù)巍糯,或是帶有普通參數(shù)的函數(shù),不建議使用inline客扎,編譯器會(huì)給我們一個(gè)提醒鳞贷,提示無性能提升;
2.帶有l(wèi)ambda函數(shù)參數(shù)的函數(shù)虐唠,建議使用inline搀愧,能顯著提高性能;
3.inline提高效率的原因疆偿?
在kotlin中咱筛,因?yàn)槌霈F(xiàn)了大量的高階函數(shù)--「高階函數(shù)是將函數(shù)用作參數(shù)或返回值的函數(shù)」,使得越來越多的地方出現(xiàn)函數(shù)參數(shù)不斷傳遞的現(xiàn)象,每一個(gè)函數(shù)參數(shù)都會(huì)被編譯成一個(gè)對(duì)象杆故,使得內(nèi)存分配(對(duì)于函數(shù)對(duì)象和類)和虛擬調(diào)用會(huì)增加運(yùn)行時(shí)間的開銷迅箩。所以才會(huì)出現(xiàn)inline內(nèi)聯(lián)函數(shù)〈︻酰可以通過inline的標(biāo)注饲趋,把原本需要生成的一個(gè)類的開銷節(jié)省了,同時(shí)也少了一層方法棧的調(diào)用撤蟆。
inline的其他作用
1.支持return退出函數(shù)
在上面例子中奕塑,我們?cè)趌ambda表達(dá)式可以直接return返回,但是暫時(shí)還不支持continue和break家肯,據(jù)說后面會(huì)支持龄砰。
2.禁止內(nèi)聯(lián):noinline
官網(wǎng)翻譯:如果希望只內(nèi)聯(lián)一部分傳給內(nèi)聯(lián)函數(shù)的lambda表達(dá)式函數(shù),那么可以用noinline標(biāo)記不希望內(nèi)聯(lián)的函數(shù)參數(shù)讨衣。
看下面的例子
看①②兩處换棚,一個(gè)用noinline修飾,一個(gè)沒有反镇,然后它們?cè)趥鬟f過程中明顯的差異固蚤,②中就直接報(bào)錯(cuò)了。
為什么呢歹茶?因?yàn)?strong>內(nèi)聯(lián)函數(shù)的「函數(shù)參數(shù)」不允許作為參數(shù)傳遞給非內(nèi)聯(lián)函數(shù)夕玩,如果要正常使用,那么我們需要把取消掉辆亏,當(dāng)成一個(gè)普通的參數(shù)傳遞過去风秤。
3.內(nèi)聯(lián)函數(shù)支持具體的類型參數(shù)的聲明reified
舉個(gè)例子:
fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
var p = parent
while (p != null && !clazz.isInstance(p)) {
p = p.parent
}
@Suppress("UNCHECKED_CAST")
return p as T?
}
我們是這樣使用它的
treeNode.findParentOfType(MyTreeNode::class.java)
然后呢,這樣寫不優(yōu)雅,我們期望這樣寫:
treeNode.findParentOfType<MyTreeNode>()
所以,我們可以對(duì)它進(jìn)行改造下:
inline fun <reified T> TreeNode.findParentOfType(): T? {
var p = parent
while (p != null && p !is T) {
p = p.parent
}
return p as T?
}
這樣就可以了罢维!
4.crossinline
局部加強(qiáng)內(nèi)聯(lián)優(yōu)化谒养,讓內(nèi)聯(lián)函數(shù)里的函數(shù)類型參數(shù)可以間接被調(diào)用玻募,代價(jià)是不能在lambda表達(dá)式里使用return渗常,用于參數(shù)偎巢。
看下面的例子拟糕,嵌套使用會(huì)報(bào)錯(cuò):
我們加上crossinline參數(shù):
可以正常調(diào)用了累提。