三个 kotlin inline 使用场景

6 阅读1分钟

1. inline + reified — 运行时保留泛型类型

  private inline fun <reified T> logWithTag(message: String) {
      val tag = T::class.java.simpleName  // 普通泛型做不到,类型擦除后拿不到 T::class                                                                     
      ...                                                                                                                                                  
  }

logWithTag("...") // TAG 自动为 "MainActivity"

为什么要 inline:普通泛型 T 在运行时被擦除,无法使用 T::class。inline 将函数体内联到调用处,reified 让编译器用具体类型替换 T,从而在运行时拿到真实类型。

2. inline 高阶函数 — 消除 lambda 对象开销

  private inline fun measureTimeAndLog(tag: String, block: () -> Unit) {
      val start = SystemClock.elapsedRealtime()
      block()  // 编译后直接展开,不创建 Function 对象
      ...
  }

为什么要 inline:不加 inline,每次调用都会 new 一个匿名 Function 对象。对于高频调用的埋点/工具方法,内联后零对象分配,减少 GC 压力。

3. inline + crossinline — 安全约束 lambda 控制流

  private inline fun runOnUiSafely(crossinline action: () -> Unit) {
      runOnUiThread { action() }  // action 被传递给另一个 lambda,需要 crossinline
  }

为什么要 crossinline:inline 的 lambda 允许非局部 return(直接 return 外层函数),但当 lambda 被传给 runOnUiThread 这样的间接执行上下文时,非局部 return 会导致控制流混乱。crossinline 禁止非局部 return,保证安全。