Kotlin 入门到进阶(32) -- inline、noinline、crossinline

inline 内联函数
编译时,会将 inline 内部逻辑,迁移到调用方内部,形成整体代码块。由于无需单独创建实例,所以运行效率比常规创建实例方式更高

// 此函数为内联函数,传入一个lambda表达式
inline fun inlineTest(block: () -> Unit) {
    println("inlineTest")
    block()
}

// 此函数为非内联函数,也是传入一个lambda表达式
fun test(block: () -> Unit) {
    println("test")
    block()
}

fun main() {
    println(measureTimeMillis {
        inlineTest {
            println("main inlineTest")
        }
    })

    println(measureTimeMillis {
        test {
            println("main test")
        }
    })
}

# inlineTest
main inlineTest
1
test
main test
9

inline函数执行时间为1,非inline函数执行时间为9

反编译后的内容

public final class MainKt {
   public static final void main() {
     // ①此处为inline函数的调用过程
      long start$iv = System.currentTimeMillis();
      System.out.println("inlineTest");
      System.out.println("main inlineTest");
      long var6 = System.currentTimeMillis() - start$iv;
      System.out.println(var6);

     // ②此处为非inline函数的调用过程
      start$iv = System.currentTimeMillis();
      test((Function0)null.INSTANCE);
      var6 = System.currentTimeMillis() - start$iv;
      System.out.println(var6);
   }

   // ③在编译器中可以看到此处inline函数并没有调用的地方
   public static final void inlineTest(@NotNull Function0 block) {
      Intrinsics.checkNotNullParameter(block, "block");
      int $i$f$inlineTest = false;
      System.out.println("inlineTest");
      block.invoke();
   }

   public static final void test(@NotNull Function0 block) {
      Intrinsics.checkNotNullParameter(block, "block");
      System.out.println("test");
      block.invoke();
   }

   // $FF: synthetic method
   public static void main(String[] args) {
      main();
   }
}

noinline 不内联
noinline就是非内联的意思,也就是表明被noinline修饰的参数强制不允许内联,此参数作为一个普通的函数引用传递,并且noinline必须搭配inline使用

fun main() {
    noinlineTest({
        println("main inline")
    }, {
        println("main noInline")
    })
}

// 定义一个内联函数,第一个参数可内联使用,第二个参数使用noinline修饰,强制不内联
inline fun noinlineTest(block: () -> Unit, noinline no: () -> Unit) {
    println("noinlineTest")
    block()
    no()
}

# log
noinlineTest
main inline
main noInline

反编译后内容

public final class NoinlineKt {
   public static final void main() {
        // ① no参数为一个Function,直接实例化了
      Function0 no$iv = (Function0)null.INSTANCE;
        // ② noinlineTest函数中打印的日志
      System.out.println("noinlineTest");
        // ③ block函数内代码直接拷贝到这
      System.out.println("main inline");
      // ④ 执行no参数具体的代码
      no$iv.invoke();
   }

   public static final void noinlineTest(@NotNull Function0 block, @NotNull Function0 no) {
      Intrinsics.checkNotNullParameter(block, "block");
      Intrinsics.checkNotNullParameter(no, "no");
      int $i$f$noinlineTest = false;
      System.out.println("noinlineTest");
      block.invoke();
      no.invoke();
   }

   // $FF: synthetic method
   public static void main(String[] args) {
      main();
   }
}

crossinline
意思为强制内联的意思,它表示被修饰的lambda参数强制执行内联作用,一般我们见到的使用它的地方都是在内联函数中使用了lambda表达式,并且在此表达式调用了内联函数的lambda参数,此时如果不使用crossinline修饰参数,编译器会报错。
不常用

详细说明:https://mp.weixin.qq.com/s/0yNuu41DTtYexE4DvABR7g

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容