一、前言
内联本质上就是用空间换取时间的一个操作,将被关键字修饰的函数或者其它属性直接嵌入主函数中,使得加载的过程中函数的运行效率大大提高,Kotlin中的内联和其他语言的内联差不多,只是分的更细,由于自身语言的特性又有一些新的用法。
二、内联函数
1. inline 的用法
只需在函数前加inline关键字即可实现函数的内联
inline fun inlineTest(){
println("wresource write")
}
这样就实现了函数的内联,即嵌入主函数中进行执行,这样做的好处是使用此函数时不需要再次调用函数进行代码的执行,坏处是由于不是在函数中执行,可能会消耗更多的内存,但执行速度就快很多,这些的实现细节可以查看class文件的反编译文件进行求证,这里就不展示了
2. noinline 的用法
当我们遇到一个场景,有些参数不需要内联,这时候如果还是inline开头的函数就默认都是内联,所以noinline就此产生,满足我们的个性化需求
//这边为了比较明显的比较效果选择函数型参数的内联和禁用内联比较
inline fun someNoinlineTest(doInline:() -> Unit,noinline doNoInline:() -> Unit){
//这里的invoke时执行lambda表达式的意思
doInline.invoke()
doNoInline.invoke()
}
同样这边也可以对内联进行反编译的验证,这部分有兴趣的可以试试
3. crossinline 的用法
一般来讲lambda表达式是不能进行返回的,但内联函数比较特殊,是直接嵌入主函数中进行执行的,故使用inline的lambda表达式就可以进行局部的返回,这时又出现了一个问题,不想要返回怎么办?crossinline就这样出现了,利用crossinline修饰的lambda表达式不允许返回
inline fun crossLineTest(crossinline lambda:() -> Unit){
normal{
lambda()
}
}
//主函数
fun main(){
noinlineTest(::doSomething1,::doSomething2)
crossLineTest {
//会报错
return
}
}
上述部分将lambda表达式和函数类型讲的有点乱了,不过其实二者其实是一样的,差别不是很大,至少在kotlin这个语言中是这样的
三、内联属性和内联类
这部分和内联函数的原理是一样的,同样也是为了提高速度牺牲内存
1.内联属性
在getter或者setter前添加inline关键字即可
//给get方法设置内联
val func : Func
inline get() = ...
//给set方法设置内联
var func2 : Func2
get() = ...
inline set(s) {...}
//给整个属性设置内联
inline var func3 :Func3
get() = ...
set(s){...}
内联其他特性和内联函数的用法类似就不过多叙述了,貌似使用的也不多,一般内联函数的实现较多
2.内联类
这个作用仍然是减少运行时间的损耗,
在kotlin 1.3版本时是使用inline进行修饰内联类
//主构造函数必须有一个不可变的属性
inline class Test(val name:String){
}
在kotlin1.5 版本时进一步提高内联类的性能,使用value代替inline进行内联的修饰
value class Test(val name:String){
}
四、总结
总体来讲内联就是为了提高运行速度以空间换取时间,不能滥用,使用场景需要比较合适的情况下才能发挥其最大的作用,有问题欢迎评论区留言哦