一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
本篇文章主要讲解内联函数的基本使用
一个基本内联函数的声明如下:
inline fun iTest() {
}
可以看到只要在普通的函数加一个inline
即可,但是这样声明的内联函数编译器会报如下警告:
翻译下:这样的内联函数声明是没有意义的,最好的使用是搭配函数类型的方法参数使用。
我们首先要先明确下普通函数增加inline
的意义,我们举一个例子对比下增加inline
的函数和普通函数:
在main
方法中分别调用了这两个方法,我们反编译成java代码看下:
我们只看到了iTest2()
普通方法的调用,iTest()
内联方法不见了?
其实iTest()
内联方法不是不见了,而是把该方法体中的代码给移植
或者平铺
到了调用处,也就是这个例子的main
方法中。
这样做的意义是什么?先不要急,我们再看一个例子,分别给普通方法还有内联方法增加一个函数类型的方法参数:
反编译成java代码看下:
内联方法iTest()
还是将方法体中还有函数类型中的代码移植到了调用处,而普通方法iTest()
则是传入一个Function0
类型的对象。
换句话说,iTest()
内联函数的调用增加了一个函数类型却没有创建额外的对象,而是将函数类型中的内容移植到了调用处;而普通方法iTest()
则不同,它是将函数类型转换
成了一个Function0
类型对象,并作为参数传入到方法中。
看到这里我们就可以总结出使用方法增加inline
转变成内联函数的好处:
-
方法参数中如果存在函数类型,内联函数会将函数类型中的代码移植到调用处,而不会额外创建
FunctionX
对象,减少对象创建的开销
; -
由于内联函数是将函数体中的内容移植到调用处,这就可以减少调用方法栈的深度,就像kotlin中存在一个
尾递归优化特性
也是为了防止递归方法调用导致方法栈深度过深,以便提高性能;