内联函数
在JVM中每次函数调用,都会进行 操作栈 操作(栈帧),会增加内存使用和开销。
另外传入的
lambda
函数 参数,也会 内存分配(创建类和对象)。
inline
使用 内联 (inline) 可以避免上面的开销,通过把 函数的代码 直接插入 调用处,
而不是 调用函数 和 创建lambda
函数类和对象。
使用 inline
声明 内联函数,语法:
kotlin
inline fun xxx() { }
inline 代码分析
举例,lock()
函数 是内联函数:
kotlin
lock(l) { foo() }
相应的代码,编译 最终是 以下形式:
kotlin
l.lock()
try {
foo()
} finally {
l.unlock()
}
让我们看下 lock
函数的声明:
kotlin
inline fun <T> lock(lock: Lock, body: () -> T): T { ...... }
noinline 和 crossinline
- 内联函数中,lambda参数 可以选择 不内联 ,使用
noinline
关键字 - 对于 禁止 直接
return
的lambda
函数参数,使用crossinline
关键字
更多说明:
- 正常 lambda 函数,不允许 直接return,而是
return@label
方式; - 内联的 lambda 函数参数,允许 直接返回;
- 内联的 lambda 函数,在 另一个对象或函数中调用时,不能直接返回函数,使用
crossinline
声明避免直接返回。
代码说明
下面以 test()
runTaskBlocking()
runTask()
来分析 直接返回 和 crossinline
禁止直接返回 场景:
kotlin
import java.util.concurrent.Executors
// forEach 和 test 都是 内联函数,支持直接返回
inline fun test(printer: () -> Unit): Boolean {
(1..3).forEach {
printer()
if (it == 2) return false
}
return true
}
val executor = Executors.newCachedThreadPool()
// 直接内联代码,lambda函数 允许直接返回
inline fun runTaskBlocking(task: () -> Unit) {
task()
}
// 当 内联lambda函数 参数,在其他 匿名函数或对象 使用时,无法直接返回(non-local return)
inline fun runTask(crossinline task: () -> Unit) {
executor.submit {
task()
}
}
fun main(args: Array<String>) {
runTaskBlocking {
println("run task blocking")
return
}
runTask {
println("run task")
// crossinline 不支持直接返回
// return
}
}