你需要懂的Kotlin内联函数那些事一

1,390 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

本篇文章主要讲解内联函数的基本使用

一个基本内联函数的声明如下:

inline fun iTest() {
}

可以看到只要在普通的函数加一个inline即可,但是这样声明的内联函数编译器会报如下警告:

image.png
翻译下:这样的内联函数声明是没有意义的,最好的使用是搭配函数类型的方法参数使用。

我们首先要先明确下普通函数增加inline的意义,我们举一个例子对比下增加inline的函数和普通函数:

image.png

main方法中分别调用了这两个方法,我们反编译成java代码看下:

image.png
我们只看到了iTest2()普通方法的调用,iTest()内联方法不见了?

其实iTest()内联方法不是不见了,而是把该方法体中的代码给移植或者平铺到了调用处,也就是这个例子的main方法中。

这样做的意义是什么?先不要急,我们再看一个例子,分别给普通方法还有内联方法增加一个函数类型的方法参数:

image.png

反编译成java代码看下:

image.png

内联方法iTest()还是将方法体中还有函数类型中的代码移植到了调用处,而普通方法iTest()则是传入一个Function0类型的对象。

换句话说,iTest()内联函数的调用增加了一个函数类型却没有创建额外的对象,而是将函数类型中的内容移植到了调用处;而普通方法iTest()则不同,它是将函数类型转换成了一个Function0类型对象,并作为参数传入到方法中。

看到这里我们就可以总结出使用方法增加inline转变成内联函数的好处:

  • 方法参数中如果存在函数类型,内联函数会将函数类型中的代码移植到调用处,而不会额外创建FunctionX对象,减少对象创建的开销

  • 由于内联函数是将函数体中的内容移植到调用处,这就可以减少调用方法栈的深度,就像kotlin中存在一个尾递归优化特性也是为了防止递归方法调用导致方法栈深度过深,以便提高性能;