一、概念
inline(内联): 编译时将函数的代码拷贝到调用的地方。
noinline(非内联): 内联高阶函数的形参中,不希望内联的lambda参数。
crossinline: 内联高阶函的形参中的lambda不能有非局部return,该lambda需要间接调用就需要。
二、使用分析
1、局部返回:只返回当前代码块。
lambda表达式默认最后一行是返回值,不能使用非局部return,即只能使用局部return[即带标签的return@label]
kotlin
fun main() {
hihgerFun lambdaOne@{
println("called lambdaOne")
return@lambdaOne
}
}
fun hihgerFun(block:() -> Unit) {
block()
}
2、inline内联
inline修饰的函数,内联函数。内联函数不仅可以内联自己函数体内部的代码,还可以内联函数体内部函数体的代码(Lambda表达式中的代码)。
kotlin
public void initView(savedInstanceState: Bundle?) {
.......//省略代码
higherFun2 {
Log.d("Cding", "=====================higherFun2 lambda 1")
//inline高阶函数中lambda表达式内,可以直接return,return的是调用该该高阶函数的外围代码函数。
// 该处return后面的代码就不会执行,并且调用该高阶函数的外围代码的后面代码也不会执行了。
return
Log.d("Cding", "=====================higherFun2 lambda. 2")
return@higherFun2 "higherFun2"
Log.d("Cding", "=====================higherFun2 lambda. 3")
"String of return."
}
}
private inline fun higherFun2(block: (Int) -> String) {
block.invoke(200)
Log.d("Cding", "=====================higherFun2 before return.")
return
Log.d("Cding", "=====================higherFun2 after return.")
}
ini
编译后的代码higherFun2直接移到了被调用的地方
public void initView(@Nullable Bundle savedInstanceState) {
this.extFun();
Function1 lambda1 = (Function1)null.INSTANCE;
Function1 lambda2 = (Function1)null.INSTANCE;
this.higherFun((Function1)null.INSTANCE);
int $i$f$higherFun2 = false;
int it = true;
int var7 = false;
//higherFun2的代码
Log.d("Cding", "=====================higherFun2 lambda 1");
String str = "String of return.";
}
三、noinline
内联高阶函数的函数类型参数只能传递给内联高阶函数, 不能传递给普通高阶函数, 此时可以使用noinline禁止该lambda参数内联。
kotlin
inline fun hightFunNoLine(block1: (Int,String) -> String, noinline block2: () -> Unit){
val start = 0
val end = "end"
block1.invoke(start, end)
commonHigherFun(block2)
}
fun commonHigherFun(block: () -> Unit){
block.invoke()
}
block2如果没有noinline修饰,是不能传递给commonHigherFun高阶函数的。noinline关键字来禁用其内联。
四、crossinline
crossinline:局部加强内联优化,让内联函数里的函数类型的参数可以间接被调用,代价是不能在Lambda表达式里使用return。
kotlin
/**
* 在inline高阶函数内部,lambda由于inline的原因是可以非局部return。
* 内联高阶函数的匿名类对象中使用lambda表达式的时候,lambda表达式不允许非局部return,也就是裸return那种。
* 调用
*/
private inline fun higherFun3(crossinline block: (Int, String) -> String){
val start = 0
val end = "end"
val function = object: MFunction{
override fun invoke(){
block(start, end)
}
}
}
private interface MFunction{
fun invoke()
}