内联函数(inline)
1. 什么是内联函数?
内联函数是 Kotlin 中通过 inline 关键字修饰的函数,它的主要作用是在编译时将函数体直接插入到调用处,从而减少函数调用的开销(如栈帧分配、参数传递等)。内联函数特别适合与高阶函数(以 Lambda 为参数的函数)结合使用,可以避免 Lambda 表达式的运行时开销。
语法示例
inline fun <T> measureTimeMillis(block: () -> T): T {
val start = System.currentTimeMillis()
val result = block()
println("Time taken: ${System.currentTimeMillis() - start} ms")
return result
}
2. 为什么使用内联函数?
优点
- 性能优化
- 消除高阶函数中 Lambda 的额外对象分配(避免创建匿名类实例)。
- 减少函数调用的栈帧开销。
- 支持非局部返回(Non-local return)
- 普通 Lambda 中不能直接使用
return返回外层函数,但内联函数的 Lambda 可以。
inline fun forEach(list: List<Int>, action: (Int) -> Unit) { for (item in list) action(item) } fun findFirstNegative(list: List<Int>): Int? { forEach(list) { if (it < 0) return it } // 直接返回外层函数 return null } - 普通 Lambda 中不能直接使用
缺点
- 内联函数会导致代码膨胀(函数体被复制到每个调用处),因此仅适合短小的函数。
3. 内联函数的限制
- 不能递归调用
递归内联会导致无限代码展开,编译报错。 - 避免内联大函数
函数体过大会显著增加生成的字节码大小。 - 部分参数禁止内联
使用noinline关键字标记不需要内联的 Lambda 参数:inline fun foo(block1: () -> Unit, noinline block2: () -> Unit) { block1() block2() // block2 不会被内联 }
4. 实际应用场景
场景 1:性能敏感的高阶函数
inline fun <T> List<T>.fastFilter(predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in this) if (predicate(item)) result.add(item)
return result
}
场景 2:DSL 构建
内联函数允许 DSL 中直接使用 return 控制流:
inline fun buildString(action: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.action()
return sb.toString()
}
val result = buildString {
append("Hello")
if (true) return@buildString // 直接返回
}
5. 内联属性(inline + 属性)
Kotlin 还支持将属性的 getter/setter 内联:
val foo: Int
inline get() = 42
var bar: String
inline get() = "Kotlin"
inline set(value) { println(value) }
总结
| 特性 | 说明 |
|---|---|
inline | 函数体直接插入调用处,优化高阶函数性能。 |
noinline | 禁止特定 Lambda 参数内联。 |
| 非局部返回 | 允许 Lambda 中直接返回外层函数。 |
| 适用场景 | 短小的高阶函数、DSL 构建、性能敏感代码。 |
提示:在 Android 开发中,内联函数常用于减少
RecyclerView.Adapter或View.OnClickListener中的 Lambda 开销。
