Kotlin-23-inline+noinline+crossinline

目录

1、inline 背景

2、inline 原理

3、noinline

4、crossinline

5、注意


 

1、inline 背景

inline---内联函数

当我们在使用高阶函数的时候,因为除了高阶函数本身是个函数以外,它的参数或者返回值也是一个Lambda函数,lambda函数内部还有局部变量,当在编译运行的时候,因为每一个Lambda函数都是一个对象,并且还会捕获一个闭包及闭包内会访问到的变量。 这样在内存分配(对于函数对象和类)和虚拟机调用上都会加大运行时间开销。

为了解决高阶函数所带来的额外开销,kotlin加入了inline关键字。

注意:过多的使用inline关键字会对编译器造成很大的性能压力,所以我们建议只在高阶函数中使用inline关键字。

2、inline 原理

代码在编译以后,会将内联函数的函数体复制到调用处。

下面左边是我们的inline函数,右边是我们编译后的class文件。

从编译后的class可以看出,inline的函数体会被直接复制到调用该内联函数的地方。

                          

3、noinline

因为inline是用来修饰高阶函数的,又因为被inline修饰的高阶函数,其参数中的lambda函数也会隐式变成inline函数,但如果我们不想要将lambda参数内联化的话,就可以使用noline关键字。

下面左边是kotlin代码,右边是编译后的class文件,绿色框中,就是我们内联化的 lambda函数a,红色就是没有被内联化的lambda函数b。

        

4、crossinline

crossinline的作用就是:不允许inline的lambda函数中断外部函数执行。

  • 在kotlin中,函数内部lambda是不允许中断外部函数执行的。(如果有return检查期会报错)
fun test1(a:()->Unit){
    a.invoke()
    return
    println("我在return后面")
}

fun main() {
    test1 { println("我是Lambda函数a") 
    //return--------------------------------报错,无法return
    }

    println("我在test1后面")
}
//输出结果
我是Lambda函数a
我在test1后面
  • inline修饰的lambda可以中断外部函数调用(原理:会将return复制到main函数中,所以return后面的语句就无法执行了)
inline fun test1(a: () -> Unit) {
    a.invoke()
    return
    println("我在return后面")
}

fun main() {
    test1 {
        println("我是Lambda函数a")
        return
    }
    println("我在test1后面")
}
//输出结果
我是Lambda函数a
  • 在inline的修饰的高阶函数中,将参数中的lambda函数用crossinline修饰就不会中断外部函数的执行。
inline fun test1(crossinline a: () -> Unit) {
    a.invoke()
    return
    println("我在return后面")
}

fun main() {
    test1 {
        println("我是Lambda函数a")
//        return-----------------------报错,无法使用return
    }
    println("我在test1后面")
}
//输出结果
我是Lambda函数a
我在test1后面

5、注意

break 和 continue 在内联的 lambda 表达式中目前还不可用。



 

 

 

发布了82 篇原创文章 · 获赞 16 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/qq_34589749/article/details/103669834