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()
}
相关推荐
zhangphil1 小时前
Android简洁缩放Matrix实现图像马赛克,Kotlin
android·kotlin
m0_512744641 小时前
极客大挑战2024-web-wp(详细)
android·前端
lw向北.1 小时前
Qt For Android之环境搭建(Qt 5.12.11 Qt下载SDK的处理方案)
android·开发语言·qt
不爱学习的啊Biao1 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
Clockwiseee2 小时前
PHP伪协议总结
android·开发语言·php
mmsx8 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
众拾达人11 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
吃着火锅x唱着歌12 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
_Shirley13 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙
hedalei15 小时前
RK3576 Android14编译OTA包提示java.lang.UnsupportedClassVersionError问题
android·android14·rk3576