kotlin中inline、noinline、crossinline

一、概念

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()
}
相关推荐
androidwork4 小时前
Android LinearLayout、FrameLayout、RelativeLayout、ConstraintLayout大混战
android·java·kotlin·androidx
每次的天空4 小时前
Android第十三次面试总结基础
android·面试·职场和发展
wu_android4 小时前
Android 相对布局管理器(RelativeLayout)
android
李斯维6 小时前
循序渐进 Android Binder(二):传递自定义对象和 AIDL 回调
android·java·android studio
androidwork6 小时前
OkHttp 3.0源码解析:从设计理念到核心实现
android·java·okhttp·kotlin
莉樱Yurin6 小时前
Kotlin/CLR 让Kotlin走进.NET世界
kotlin
像风一样自由7 小时前
【001】frida API分类 总览
android·frida
casual_clover7 小时前
Android 之 kotlin 语言学习笔记四(Android KTX)
android·学习·kotlin
移动开发者1号8 小时前
Android 大文件分块上传实战:突破表单数据限制的完整方案
android·java·kotlin
移动开发者1号8 小时前
单线程模型中消息机制解析
android·kotlin