Kotlin inline、noinline 和 crossinline 的区别

Kotlin inline、noinline 和 crossinline 的区别

  • 间接调用:比如作为参数传递给其他函数或作为返回值返回
  • 非局部返回:Lambda 中 return 直接返回外层函数的情况,而局部返回就是 return 返回到这个函数本身

inline 内联函数

  • 用于标记一个函数为内联函数,在编译时将函数体代码(包括参数)直接内联展开嵌入到调用处(函数中的代码直接复制到调用它的地方),而不是通过传统函数调用(压栈进栈)的方式执行,从而减少函数调用和对象创建等额外的开销,inline 适合用在包含 Lambda 参数的函数上
  • 函数调用:减少函数调用栈的开销(减少函数栈的层级),调用一个方法是一个压栈和出栈的过程
  • 对象创建:调用高阶函数(带 Lambda 参数)而创建函数对象(比如 Function 接口的实例)
  • inline 不仅让函数调用被内联,还会让函数参数也被内联,它可以让函数参数里面的直接 return 生效(因为普通 Lambda 不能直接使用 return),在 inline 函数的 Lambda 中可以使用 return 直接返回到调用该函数的外层函数(而非 Lambda 自身),相当于会退出外层函数,不过这其实算是一个缺点,因为代码逻辑很容易出现不是想象中预期的结果,所以引入了一种方式解决,就是利用 noinline 或 crossinline 来限制在 Lambda 中直接使用 return 的行为
kotlin 复制代码
inline fun fun01(block: () -> Unit) {
    block() //调用 Lambda
}
fun main() {
    fun01 {
      println("Test01") 
      return //直接退出 main 函数(支持 return 返回到外层函数),如果没有 inline 标记的话,编译器会报错(不过可以改成 return@fun01,但是这样只会退出 Lambda)
    }
    println("Test02") //这行代码不会执行
}

noinline 禁止内联特定参数

  • 与 inline 结合使用,用于标记一个函数的某个参数(通常是 Lambda)不被内联,Lambda 会像普通函数参数一样(作为普通的函数对象传递),相当于使用 noinline 来指定某个函数参数不使用 inline 带来的特性
  • 间接调用:如果需要将 Lambda 传递给其他非内联函数时(因为内联函数的函数参数是不允许作为参数传递给非内联的函数的),就必须使用 noinline,如果需要将 Lambda 作为返回值返回时,必须使用 noinline
kotlin 复制代码
inline fun fun02(
    action: () -> Unit,              //内联
    noinline callback: () -> Unit    //不内联
) {
    action()
    callback()
}
fun main() {
    fun02({
        println("Test01")
        //return  //这里直接用 return 编译器不会报错
    }, {
        println("Test02")
        //return  //这里直接用 return 编译器会报错
    })
    println("Test03")
}

crossinline 跨内联限制非局部返回

  • 用于标记一个函数的某个 Lambda 参数,表示该 Lambda 可以被间接调用,但禁止在 Lambda 中使用 return(可以确保 Lambda 中不会出现非局部返回,防止 return 意外跳出外层函数),避免因内联导致 return 作用域混乱
  • 保持内联优化:crossinline 标记的 Lambda 仍会被内联展开(除非被传递到非内联函数中)
kotlin 复制代码
inline fun fun03(crossinline block: () -> Unit) {
    block() //调用 block 时,不能通过 return 返回到外层函数
}
fun main() {
    fun03 {
        return //这里直接用 return 编译器会报错(crossinline 禁止使用 return)
    }
}

总结

  • 普通函数(带 Lambda 参数),可以间接调用,不允许非局部返回
  • inline 标记整个函数为内联函数,不可以间接调用,允许非局部返回
  • noinline 标记禁止某一个参数内联,可以间接调用,不允许非局部返回
  • crossinline 标记跨内联,保持内联优化,可以间接调用,不允许非局部返回
相关推荐
程序员煊子5 小时前
用 Cursor 从零搭一个 Compose 本地记账 App:实战记录与源码解析
android·kotlin·compose·cursor
alexhilton7 小时前
面向Android开发者的Google I/O 2026
android·kotlin·android jetpack
idingzhi14 小时前
A股量化策略日报(2026年05月22日)
android·开发语言·python·kotlin
赏金术士15 小时前
Android 动画对比指南:View 系统 vs Jetpack Compose
android·kotlin·compose
plainGeekDev17 小时前
Kotlin核心:空安全都搞不明白,还敢说熟练Kotlin?
android·面试·kotlin
jzlhll12318 小时前
Kotlin 协程高级用法之 NonCancellable
android·开发语言·kotlin
JohnnyDeng9420 小时前
Paging 3 分页加载架构全解析:从数据源到 UI 的完整链路
android·ui·kotlin
高林雨露21 小时前
kotlin 相关code
开发语言·kotlin
huaCodeA1 天前
Android面试-Kotlin作用域函数
android·面试·kotlin
QING6182 天前
Kotlin inline 实战详解 —— 新手须知
android·kotlin·android jetpack