资讯动态

Kotlin 内联函数(inline)一篇看懂

发布时间:2026/8/27 15:42:04 来源:尧图企业网站定制
Kotlin 内联函数inline一篇看懂Kotlin 的 inline 本质上只有一句话把函数代码复制到调用处而不是正常函数调用。它主要解决两个问题Lambda 带来的对象创建性能损耗Lambda 里无法直接 return 的限制一、先理解普通函数是怎么执行的funtest(){println(hello)}funmain(){test()}正常情况下main() ↓ 调用 test() ↓ 执行 println这是一次函数跳转。二、inline 做了什么inlinefuntest(){println(hello)}funmain(){test()}编译后效果类似funmain(){println(hello)}也就是不调用了直接把代码贴进来所以叫内联inline类似 C 语言宏展开三、为什么 Kotlin 特别需要 inline因为 Kotlin 大量使用Lambda例如list.forEach{println(it)}实际上{ println(it) }这个 Lambda会生成对象会额外产生调用在 Android 中RecyclerViewFlowCompose点击事件高阶函数都会频繁创建 Lambda。如果大量使用会产生更多 GC更多对象性能损耗所以 Kotlin 官方大量使用 inline。四、最经典案例高阶函数不使用 inlinefunexecute(block:()-Unit){block()}调用execute{println(hello)}这里会生成一个 Lambda 对象相当于new Function0()。Android 高频调用下会有损耗。使用 inline 后inlinefunexecute(block:()-Unit){block()}调用execute{println(hello)}编译后类似println(hello)Lambda 对象没了。这就是inline 最大价值。五、Android 为什么大量使用 inline你会发现很多系统 API 全是inlinerunletapplyalsousewithforEach因为这些函数调用频率极高大量使用 Lambda六、最容易看懂的 Android 实战场景1点击防抖不用 inlinefunsetSafeClick(block:()-Unit){block()}// 调用setSafeClick{login()}会创建 Lambda 对象。用 inlineinlinefunsetSafeClick(block:()-Unit){block()}高频点击时少对象创建更流畅。场景2RecyclerViewRecyclerView bind 非常高频。不推荐funbind(block:()-Unit){block()}// onBindViewHolderbind{holder.tv.textitem.name}每次 bind 创建 Lambda创建匿名类。列表滑动会产生大量对象。推荐inlinefunbind(block:()-Unit){block()}尤其瀑布流、长列表、高频刷新收益明显。场景3ViewBinding 扩展Android 常见inlinefunT:ViewBindingActivity.binding(block:()-T):T{returnblock()}// 调用valbindingbinding{ActivityMainBinding.inflate(layoutInflater)}避免 Lambda 额外开销。场景4SharedPreferences 编辑经典inlinefunSharedPreferences.edit(action:SharedPreferences.Editor.()-Unit){valeditoredit()action(editor)editor.apply()}// 调用sp.edit{putString(name,Tom)}这是 Android 最经典 inline 实战之一。七、inline 最重要的能力支持 return这是很多人真正没理解的点。普通 Lambda 不能直接 returnfuntest(block:()-Unit){block()}funmain(){test{return// 报错}}因为return不知道该退出谁。inline 可以inlinefuntest(block:()-Unit){block()}funmain(){test{return}println(不会执行)}因为 inline 后相当于funmain(){returnprintln(不会执行)}所以合法。这个叫非局部返回Non-local return八、这就是为什么 forEach 能 returnlist.forEach{if(it3){return}}因为forEach是inline。九、crossinline 是什么有时候inline 虽然允许 return但函数作者不想让你 return。inlinefuntest(crossinlineblock:()-Unit){Runnable{block()}.run()}这里block被放到了另一个对象里已经不是原位置执行。所以不能 return否则test{return}逻辑会乱。所以crossinline 禁止非局部 return十、noinline 是什么inline 默认会内联所有 Lambda 参数但有时候你需要保存 Lambda当对象传递延迟执行这时候不能 inline。inlinefuntest(noinlineblock:()-Unit){}意思别内联这个 Lambda十一、最容易记忆的口诀关键字作用inline复制代码进调用处。减少 Lambda 对象提升性能支持 returncrossinline允许内联但禁止 returnnoinline不要内联这个 Lambda十二、Compose 为什么大量 inlineJetpack Compose 极度依赖Lambda高阶函数例如Column{// 本质全是 Lambda}所以 Compose 内部大量使用inline。否则UI 每次重组都会大量创建对象。十三、什么时候适合 inline推荐高频调用RecyclerView、Compose、Flow、点击事件、ViewBinding工具函数高阶函数函数参数里有Lambdablock: () - Unit优先考虑 inline。十四、什么时候别乱用 inlineinline 会增加字节码体积因为代码被复制了。所以不适合超大函数inlinefunveryBigFunction(){// ...}会导致 APK 变大。普通函数没有 Lambdainlinefunadd(a:Int,b:Int)ab意义很小。十五、Android 面试高频回答模板如果面试问Kotlin inline 有什么作用可以这样回答inline 本质是编译时函数展开。主要用于高阶函数优化。Kotlin Lambda 会生成匿名对象在 Android 高频场景下会带来对象创建、GC 压力。使用 inline 后Lambda 不再生成对象减少函数调用开销提升性能。另外 inline 支持非局部 return。Kotlin 标准库大量使用 inline例如let、apply、forEach、run。Android 中RecyclerView、Compose、Flow、点击事件封装都会大量使用 inline。十六、最终一张图彻底理解普通函数调用函数 ↓ 创建 Lambda 对象 ↓ 执行inline直接复制代码 ↓ 无对象 ↓ 无调用十七、推荐你真正去看的源码非常建议你看这些源码letapplyrunforEachuse你会发现几乎全是inline。例如publicinlinefunTT.apply(block:T.()-Unit):T{block()returnthis}这会让你真正理解 Kotlin 设计哲学。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价