深色模式
Kotlin 内联函数
内联函数的特点
减少函数调用的开销
内联函数会在编译时被“展开”(
inline
),即函数调用处的代码会被替换为函数的实际代码,从而避免了运行时的函数调用开销。用于高阶函数
Kotlin 的高阶函数会带来额外的运行时开销(创建函数对象、捕获闭包等)。通过内联,Kotlin 可以优化这些开销。
可选择性内联
可以使用
noinline
和crossinline
关键字控制哪些参数内联、哪些不内联。
内联函数的语法
- 基本用法
kotlin
inline fun performAction(action: () -> Unit) {
println("Before action")
action()
println("After action")
}
fun main() {
performAction {
println("Performing action")
}
}
编译后效果:
kotlin
fun main() {
println("Before action")
println("Performing action")
println("After action")
}
- 使用高阶函数时的性能优化
kotlin
fun main() {
val list = listOf(1, 2, 3)
list.forEach { println(it) }
}
forEach
是一个高阶内联函数,编译后会将 println(it)
直接嵌入到循环体中,避免了创建额外的 Lambda 对象。
noinline 和 crossinline
noinline
如果某个高阶函数参数不需要内联,可以用 noinline
关键字标记。
kotlin
inline fun test(block1: () -> Unit, noinline block2: () -> Unit) {
block1()
block2()
}
fun main() {
test(
{ println("Block 1") },
{ println("Block 2") }
)
}
block1
会被内联,其代码直接插入调用处。block2
不会被内联,仍然会以函数对象的形式存在。
crossinline
当 Lambda 表达式中不能使用非局部返回时,需要用 crossinline
来标记,避免潜在的错误。
kotlin
inline fun performAction(crossinline action: () -> Unit) {
println("Starting action")
// 使用 run 强制内联 Lambda
run { action() }
println("Ending action")
}
fun main() {
performAction {
println("Action executed")
// return // 会报错,因为 crossinline 禁止非局部返回
}
}
内联函数的限制
递归函数不能内联
内联函数必须在编译时完全展开,递归函数无法实现这一点。
kotlininline fun recursiveFunction(n: Int): Int { return if (n == 0) 1 else n * recursiveFunction(n - 1) // 错误 }
内联函数会增加代码体积
如果内联函数被多次调用,代码会被复制多次,从而导致编译后的代码体积增大。
不能用于非高阶函数
如果函数没有高阶参数,内联的意义不大。
内联属性
Kotlin 还支持将 get
或 set
方法标记为 inline
,优化访问器的性能。
kotlin
val pi: Double
inline get() = 3.14159
fun main() {
println(pi) // 编译后直接替换为 3.14159
}