Kt 语法统计
2026/1/31大约 2 分钟
Kt 语法统计
inline
inline 是 Kotlin 中的一个编译期优化关键字,用于函数内联(inlining)。它的核心作用是:在编译时将函数体直接“复制粘贴”到调用处,而不是像普通函数那样通过标准的函数调用机制执行。
private inline fun <R> withStopException(crossinline block: () -> R) {
runCatching(block).onFailure {
environment.log.error("Exception thrown during engine stop", it)
}
}这里使用 inline 主要是为了高效地传递 lambda 表达式 block,避免创建额外的匿名类对象(尤其在高频调用或性能敏感场景下)。
🔍 深入解释 inline
✅ 1. 为什么需要 inline?
Kotlin 的高阶函数(接收 lambda 的函数)在 JVM 上默认会生成匿名内部类(Function 对象),例如:
// 不加 inline
fun foo(action: () -> Unit) { action() }
foo { println("Hello") }✅ 2. crossinline 是什么?
为什么需要它?
- inline 函数默认允许 lambda 中使用 非局部返回(non-local return),即从 lambda 直接返回外层函数
- 但你的 block 被传给了 runCatching(一个普通函数,不是 inline 的),这意味着 block 不会立即执行,而是稍后在 runCatching 内部调用。
- 如果允许非局部返回,会导致逻辑混乱甚至崩溃。
crossinline 的作用:
禁止在 block 中使用非局部返回(如直接写 return),强制 lambda 只能做局部返回(比如 return@label 或抛异常)。
✅ 这保证了控制流的安全性。
✅ 4. 什么时候该用 inline?
| 场景 | 建议 |
|---|---|
| 高阶函数(接收 lambda) | ✅ 优先考虑 inline(尤其是小函数) |
| lambda 被立即执行 | ✅ 适合 inline |
| lambda 被保存/异步执行 | ⚠️ 必须加 crossinline(如你的例子) |
| 函数体很大或调用频繁 | ⚠️ 谨慎:inline 会增大字节码体积 |
| 普通函数(无 lambda) | ❌ 不要用 inline(无收益) |
💡 经验法则:工具型高阶函数(如 with, apply, run, also, runCatching 封装等)通常用 inline
by
internal val bootstraps: List<ServerBootstrap> by lazy {
configuration.connectors.map(::createBootstrap)
}使用了 Kotlin 的委托属性(Delegated Properties) 语法,具体是** by lazy 委托**,用于实现延迟初始化(lazy initialization)。
by lazy
- 这是 Kotlin 的属性委托(Property Delegation) 语法。
- by lazy 是 Kotlin 标准库提供的一个委托实现,用于懒加载:只有第一次访问该属性时,才执行大括号 {} 中的代码块;之后的访问直接返回缓存的结果。
- 默认是线程安全的(使用 LazyThreadSafetyMode.SYNCHRONIZED)。
🧠 补充知识:by lazy 的特性
| 特性 | 说明 |
|---|---|
| 延迟计算 | 初始化代码块只在首次访问时执行 |
| 线程安全 | 默认加锁,多线程下只初始化一次 |
| 只读属性 | 只能用于 val,不能用于 var |
| 可选模式 | 可指定线程安全策略:lazy(LazyThreadSafetyMode.NONE) { ... }(非线程安全,性能更高) |
💡 对比 Java 写法(帮助理解)
在 Java 中,要实现类似效果,通常需要手动写双重检查锁或 synchronized 方法:
private volatile List<ServerBootstrap> bootstraps;
public List<ServerBootstrap> getBootstraps() {
if (bootstraps == null) {
synchronized (this) {
if (bootstraps == null) {
bootstraps = configuration.getConnectors().stream()
.map(this::createBootstrap)
.collect(Collectors.toList());
}
}
}
return bootstraps;
}inflex
中缀函数