什么是内联(inline)函数
首先 inline
借鉴至 c++, 主要作用是降低程序的运行时间。当内联函数收到编译器的指示时,编译器将使用函数的定义体替代函数调用语句,这种替换行为发生在编译阶段而非程序运行阶段。
在kotlin中,函数就是对象,当你调用某个函数的时候,就会创建相关的对象(内存开销的原因)
下面用两个实际例子说明两种区别
非inline函数的调用过程
inline函数的调用过程
Kolin中的 inline,noinline
在Kolin中如果声明fun为 inline
,默认所有该函数用的lambda
也是内联,如下:
当前可以通过 noinline
来改变这特性
//lambda加上noinline强制不内联
inline fun doSum(a: Int, b: Int,noinline cal : (Int,Int) -> Int) : Int{
val sum = cal(a,b)
print("sum $sum")
return sum
}
Kotlin中的 return,non-local return
return
在kotlin中,return 只能用在有名字的函数或匿名函数
中,使得该函数执行完毕。
而针对lambda表达式,你不能直接使用return
报错示例:
但是可以通过 lambda
+ label
结束此lambda执行(lambda的默认是label名为函数名字)
{
//返回默认的label
doWork { return@doWork}
//返回自定义的label
doWork finish@{ return@finish}
}
fun doWork(work: () -> Unit){
}
那么如何直接在lambda中使用return ? 内联(inline函数)
doInlineWork{
//由于doInlineWork是inline标记的函数,因此可以直接使用return
return
}
}
inline fun doInlineWork(work: () -> Unit){
}
�
之所有加上 inline
后就能直接使用return
,是因为内联函数在编译的时候,将相关的代码贴入你调用的地方。
lambda
表达式也只是一段代码而已,这时候你在lambda
中的return
,相当于在你调用的方法内return
non-local return
首先知晓一个情况:一个函数中,如果存在一个lambda
表达式,在该lambda
中不支持直接进行return
退出该函数,但是匿名或者具名函数则可以,如下所示
fun outterFun() {
innerFun {
//return //错误,不支持直接return
//只支持通过标签,返回innerFun
return@innerFun
}
//如果是匿名或者具名函数,则支持
var f = fun(){
return
}
}
fun innerFun(a: () -> Unit) {}
除非,innerFun是inline
函数:
fun outterFun() {
innerFun {
return //支持直接返回outterFun
}
}
inline fun innerFun(a: () -> Unit) {}
上述这种直接在lambda
中返回外部函数的称为non-local return
(非局部返回)
Kotlin中的 crossline
crossline
是针对 non-local return
使用,让被标记的lambda
表达式不允许 non-local return
(非局部返回), 因为默认内联函数的lambda
表达式参数是允许非局部返回的(及返回外部函数)
如下:
fun outterFun() {
innerFun {
return //支持直接返回outterFun
}
}
inline fun innerFun(a: () -> Unit) {}
当通过将innerFun的lambda
参数标记为crossinline
后,return
操作将不被允许
fun outterFun() {
innerFun {
return //因为lambda参数加上了 crossinlen因此 这里就不合法
}
}
inline fun innerFun(crossinline a: () -> Unit) {}