一次性搞懂Kotlin的内联函数--inline,noinline和crossinline

Posted warmor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次性搞懂Kotlin的内联函数--inline,noinline和crossinline相关的知识,希望对你有一定的参考价值。

inline 内联函数
  编译时把函数的实现直接放到调用处,省去了参数对象的创建,减少了调用的层级。一般是用在高阶函数里。
  内联函数的参数,如果是函数类型(即lambda),调用时,可以使用return(特权),那么返回的就是调用函数的那个函数

private inline fun inLinTest(f1: () -> Unit, f2: () -> Unit )
    Log.i(TAG, "inline test")
    f1() //runOnUiThread  f1()  location 1
    f2()

//调用
inLinTest(
    Log.i(TAG, "parm1")
    return
, 
    Log.i(TAG, "parm2")
)

会被编译成如下代码

Log.i(TAG, "inline test")
Log.i(TAG, "parm1")
return
Log.i(TAG, "parm2")

  可以看到,函数的参数,甚至函数名,都被“优化”掉了,因此代码中的parm2就不会被打印。
  如果内联函数的参数是lambda,那么该参数就不能再作为函数的参数(传参)或者返回值了,因为内联函数在编译的时候,函数以及参数都没有参与到代码里,那么内存里面就没有参数了,又怎么能作为参数或者返回值呢?如果要打破这个限制就需要下面的两个东东了。
noinline
被修饰的部分不使用内联,这样的话,就可以作为函数的参数和返回值了,如下:


private inline fun inLinTest(noinline f1: () -> Unit, f2: () -> Unit )
    Log.i(TAG, "inline test")
    runOnUiThread  f1()  //f1作为参数传递,没有问题,如果需要亦可作为返回值
    f2()

//调用
inLinTest(
    Log.i(TAG, "parm1")
    // return location 1 
, 
    Log.i(TAG, "parm2")
)

  但是这样的话,调用的时候,location 1处就不能使用return返回了,因为如果返回的话,只是能出runOnUiThread(),而我们上面说的是返回函数外面一层的函数,就不成立了。
crossinline
  一般的inline函数的lamda类型的参数是不能当做参数传递的,但是加上了crossinline就可以了,但是注意不能当做函数的返回值。
  来比对一下noinline 和 crossinline
相同点:调用的时候,lambda里面不能使用return返回,都可以作为函数的参数传递。
不同点:被crossinline修饰的lambda参数,不能当做函数的返回值。
  ok,到这里,关于内联函数相关的东西就差不多了,欢迎留言跟我讨论哈~

以上是关于一次性搞懂Kotlin的内联函数--inline,noinline和crossinline的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin inline 内联函数

Kotlin:你必须要知道的 inline-noinline-crossinline

kotlin内联(inline)函数中参数默认值报VerifyError: Bad local variable type错误的解决办法

kotlin内联(inline)函数中参数默认值报VerifyError: Bad local variable type错误的解决办法

kotlin内联(inline)函数中参数默认值报VerifyError: Bad local variable type错误的解决办法

Kotlin Inline 的原理和注意点