Kotlin 内联函数 #

一、内联函数概述 #

使用 inline 关键字标记的函数,编译器会将函数代码直接复制到调用处,避免函数调用的开销。

二、inline 关键字 #

2.1 基本用法 #

kotlin
inline fun measureTime(action: () -> Unit): Long {
    val start = System.currentTimeMillis()
    action()
    return System.currentTimeMillis() - start
}

// 调用
val time = measureTime {
    Thread.sleep(100)
    println("Done")
}

2.2 编译后效果 #

kotlin
// 编译前
val time = measureTime {
    println("Hello")
}

// 编译后(近似)
val start = System.currentTimeMillis()
println("Hello")
val time = System.currentTimeMillis() - start

2.3 性能优势 #

kotlin
// 不使用 inline:每次调用都创建 Lambda 对象
fun withoutInline(action: () -> Unit) {
    action()
}

// 使用 inline:Lambda 被内联,无额外对象
inline fun withInline(action: () -> Unit) {
    action()
}

三、noinline 关键字 #

3.1 禁用内联 #

当不希望某个 Lambda 参数被内联时:

kotlin
inline fun process(
    inlineAction: () -> Unit,
    noinline nonInlineAction: () -> Unit
) {
    inlineAction()
    nonInlineAction()
}

3.2 使用场景 #

kotlin
inline fun execute(
    action: () -> Unit,
    noinline onFailure: (Exception) -> Unit
) {
    try {
        action()
    } catch (e: Exception) {
        onFailure(e)
    }
}

// noinline 允许将 Lambda 存储或传递给其他函数
inline fun storeAction(noinline action: () -> Unit) {
    val storedAction = action  // 可以存储
    storedAction()
}

四、crossinline 关键字 #

4.1 防止非局部返回 #

kotlin
inline fun execute(crossinline action: () -> Unit) {
    // 在另一个执行上下文中调用
    Runnable { action() }.run()
}

// 调用时不能使用 return
execute {
    // return  // 错误:不允许非局部返回
    println("Hello")
}

4.2 使用场景 #

kotlin
inline fun runOnUiThread(crossinline action: () -> Unit) {
    // 在 UI 线程执行
    // crossinline 确保不会意外返回外层函数
    Thread { action() }.start()
}

fun process() {
    runOnUiThread {
        // return  // 编译错误
        updateUI()
    }
    println("继续执行")
}

五、reified 关键字 #

5.1 类型参数具体化 #

kotlin
inline fun <reified T> isType(value: Any): Boolean {
    return value is T
}

isType<String>("Hello")  // true
isType<Int>("Hello")     // false

5.2 获取泛型类型 #

kotlin
inline fun <reified T> getTypeName(): String {
    return T::class.simpleName ?: "Unknown"
}

getTypeName<String>()  // "String"
getTypeName<Int>()     // "Int"

5.3 实际应用 #

kotlin
// JSON 解析
inline fun <reified T> parseJson(json: String): T {
    return Gson().fromJson(json, T::class.java)
}

val user = parseJson<User>("""{"name":"Kotlin","age":10}""")

// 启动 Activity(Android)
inline fun <reified T : Activity> Context.startActivity() {
    startActivity(Intent(this, T::class.java))
}

startActivity<MainActivity>()

5.4 创建实例 #

kotlin
inline fun <reified T : Any> createInstance(): T {
    return T::class.java.getDeclaredConstructor().newInstance()
}

val person = createInstance<Person>()

六、内联属性 #

6.1 内联属性访问器 #

kotlin
val <T> List<T>.firstOrNull: T?
    inline get() = if (isEmpty()) null else this[0]

var <T> MutableList<T>.first: T
    inline get() = this[0]
    inline set(value) { this[0] = value }

6.2 内联属性示例 #

kotlin
inline val String.halfLength: Int
    get() = length / 2

inline var StringBuilder.content: String
    get() = toString()
    set(value) {
        clear()
        append(value)
    }

七、标准库内联函数 #

7.1 let #

kotlin
public inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

7.2 run #

kotlin
public inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

7.3 apply #

kotlin
public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

7.4 also #

kotlin
public inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

7.5 use #

kotlin
// 自动关闭资源
File("test.txt").inputStream().use { input ->
    // 使用 input
}  // 自动关闭

八、内联函数的限制 #

8.1 不能内联的情况 #

kotlin
// 内联函数不能是 private 的成员
class Example {
    // 错误
    // private inline fun foo() { }
    
    // 正确
    inline fun bar() { }
}

// 内联函数不能是虚函数
open class Base {
    // 错误
    // open inline fun foo() { }
}

8.2 Lambda 参数限制 #

kotlin
inline fun example(action: () -> Unit) {
    // 不能将内联 Lambda 存储在变量中
    // val stored = action  // 错误
    
    // 可以直接调用
    action()
    
    // 使用 noinline 可以存储
}

inline fun example2(noinline action: () -> Unit) {
    val stored = action  // 正确
    stored()
}

九、实战示例 #

9.1 性能测量 #

kotlin
inline fun <T> measureTime(block: () -> T): Pair<T, Long> {
    val start = System.nanoTime()
    val result = block()
    val time = System.nanoTime() - start
    return result to time
}

val (result, time) = measureTime {
    Thread.sleep(100)
    "Done"
}
println("Result: $result, Time: ${time / 1_000_000}ms")

9.2 资源管理 #

kotlin
inline fun <T : AutoCloseable, R> T.use(block: (T) -> R): R {
    try {
        return block(this)
    } finally {
        this.close()
    }
}

FileInputStream("test.txt").use { input ->
    // 使用 input
}

9.3 条件执行 #

kotlin
inline fun debug(block: () -> Unit) {
    if (BuildConfig.DEBUG) {
        block()
    }
}

debug {
    println("Debug information")
    // 只在 DEBUG 模式执行
}

9.4 锁定执行 #

kotlin
inline fun <T> synchronized(lock: Any, block: () -> T): T {
    synchronized(lock) {
        return block()
    }
}

val lock = Any()
synchronized(lock) {
    // 线程安全操作
}

十、最佳实践 #

10.1 何时使用 inline #

kotlin
// 推荐:高阶函数
inline fun operate(action: () -> Unit) { }

// 推荐:性能敏感代码
inline fun measure(block: () -> Unit) { }

// 不推荐:普通函数
inline fun add(a: Int, b: Int) = a + b  // 没必要

10.2 合理使用 noinline #

kotlin
// 只在需要存储 Lambda 时使用
inline fun process(noinline action: () -> Unit) {
    val stored = action
    executor.execute(stored)
}

10.3 使用 reified 简化泛型 #

kotlin
// 不使用 reified
fun <T> getType(clazz: Class<T>): String {
    return clazz.simpleName
}
getType(String::class.java)

// 使用 reified
inline fun <reified T> getType(): String {
    return T::class.simpleName
}
getType<String>()

十一、总结 #

内联函数关键字:

关键字 用途
inline 内联函数和 Lambda
noinline 禁止内联特定 Lambda
crossinline 禁止非局部返回
reified 具体化泛型类型参数

下一步,让我们学习 类与对象

最后更新:2026-03-27