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()
}
相关推荐
TDengine (老段)13 小时前
TDengine 转换函数 TO_JSON 用户手册
android·大数据·数据库·json·时序数据库·tdengine·涛思数据
q***428213 小时前
SpringCloudGateWay
android·前端·后端
卫生纸不够用13 小时前
Appium-锁屏-Android
android·appium
阿拉斯攀登13 小时前
安卓工控机 OTA 升级方案(SpringBoot+MQTT)
android·spring boot·物联网·iot
顾林海14 小时前
从0到1搭建Android网络框架:别再让你的请求在"路上迷路"了
android·面试·架构
花花鱼14 小时前
android room中实体类变化以后如何迁移
android
Jomurphys15 小时前
设计模式 - 适配器模式 Adapter Pattern
android
雨白15 小时前
电子书阅读器:解析 EPUB 底层原理与实战
android·html
g***B73815 小时前
Kotlin协程在Android中的使用
android·开发语言·kotlin
A***279515 小时前
Kotlin反射机制
android·开发语言·kotlin