🌟 什么是内联函数?
简单说:
内联函数就是在编译时将函数的调用代码“展开”为函数体本身,从而避免函数调用的开销。
通常高阶函数(比如 map
, filter
, let
, run
等)都会带来额外的开销,因为它们需要创建函数对象、维护调用栈。而使用 inline
关键字修饰的函数在编译时会将其代码“拷贝”到调用处,避免这些额外开销。
🧪 基本语法
1 | inline fun doSomething(action: () -> Unit) { |
调用方式:
1 | doSomething { |
⚡ 编译后,大致等价于:
1 | println("Start") |
函数体直接“插入”到调用处。
✅ 优势
- 性能提升:避免函数调用、lambda 对象创建的开销。
- 允许非局部返回(下面详细说)
- 适合频繁调用的小型函数或高阶函数
⚠️ 注意:非局部返回(non-local return)
Lambda 中用 return
,默认是从外围函数返回的,这在内联函数中是允许的。
1 | inline fun doSomething(block: () -> Unit) { |
如果你把 doSomething
的 inline
去掉,这段代码是无法通过编译的。
🔒 使用 noinline
禁止内联某个 lambda
有时候你不希望某些 lambda 被内联,可以加 noinline
:
1 | inline fun process(a: () -> Unit, noinline b: () -> Unit) { |
常用于 将 lambda 作为值传递或多次使用 的情况。
💥 crossinline
:阻止 lambda 使用 return
有时候你必须内联,但又不允许 lambda 使用非局部 return(比如 lambda 传给另一个线程或匿名类),你可以加 crossinline
:
1 | inline fun startJob(crossinline job: () -> Unit) { |
🚀 小总结
关键字 | 作用 |
---|---|
inline |
编译时将函数体展开,提升性能,允许非局部 return |
noinline |
禁止某个 lambda 被内联(用于多次调用或当作对象传递) |
crossinline |
阻止某个 lambda 使用 return (防止非局部 return) |
✅ 典型应用场景
apply
/run
/let
等标准库函数内部都是inline
的- DSL 构建器,比如
anko
,Jetpack Compose
,Ktor
等大量用inline
优化性能和语法结构 - 性能敏感的高阶函数