1. 概述
本文将介绍在 Kotlin 中实现值交换(swap)功能的几种常见方法。
所谓 swap 函数,通常是指一个用于交换两个变量值的辅助函数或代码模式。虽然 Kotlin 标准库中没有内置 swap()
函数,但我们可以借助语言特性灵活实现。本文涵盖以下三种主流方式:
- ✅ 使用临时变量直接交换
- ✅ 利用
Pair
实现解构赋值 - ✅ 借助
also()
高阶函数“一行”完成交换
这些技巧不仅实用,还能帮助你更深入理解 Kotlin 的作用域函数和表达式特性,避免日后踩坑。
2. 使用临时变量交换
最基础、最直观的方式是引入一个临时变量进行中转。这种方式逻辑清晰,兼容所有语言,也是编译器底层常用的交换策略。
var a = 1
var b = 2
val temp = a
a = b
b = temp
assertEquals(2, a)
assertEquals(1, b)
⚠️ 虽然简单,但在实际开发中频繁写这种模板代码显得啰嗦。不过理解其原理很重要——所有高级写法本质上都是对这一过程的语法糖封装。
3. 使用 Pair 解构交换
Kotlin 的 Pair
类可以封装两个值,并支持解构赋值(destructuring declaration),非常适合用来做变量交换。
核心思路是:
✅ 先用两个变量构造一个 Pair
✅ 然后通过解构重新赋值
var x = 100
var y = 200
(x to y).apply {
x = second
y = first
}
assertEquals(200, x)
assertEquals(100, y)
这里使用了 to
操作符创建 Pair
对象(即 x to y
等价于 Pair(x, y)
),然后调用 apply
作用域函数,在其上下文中通过 first
和 second
访问原值并反向赋值。
💡 小贴士:apply
返回的是对象本身,适合需要“链式调用 + 修改自身”的场景。此处我们利用它持有了原始 Pair
的引用,从而安全完成交换。
这种写法简洁且可读性强,推荐在需要语义清晰的场合使用。
4. 使用 also() 函数实现“一行交换”
这是最“Kotlin 风格”的写法之一,利用 also()
的特性实现无临时变量的一行交换。
var a = 1
var b = 2
a = b.also { b = a }
assertEquals(2, a)
assertEquals(1, b)
🔍 关键点解析:
also{}
接收一个 lambda,执行完后返回调用者自身- 在 lambda 内部可以访问外部变量(闭包)
- 所以
b.also { b = a }
的含义是:- 先保存当前
b
的值(用于后续返回) - 执行
{ b = a }
—— 把a
的值赋给b
- 最后返回原来的
b
值
- 先保存当前
- 此时
a = ...
就等于把旧的b
值赋给a
🧠 运算顺序等效于:
val oldValueOfB = b
b = a
a = oldValueOfB
✅ 优点:代码极简,适合喜欢函数式风格的开发者
❌ 缺点:初看容易困惑,维护成本略高,建议加注释说明意图
⚠️ 注意:该写法依赖求值顺序,仅适用于可变变量(
var
),且要求类型一致或可兼容转换。
5. 总结
本文介绍了 Kotlin 中三种常见的变量交换方式:
方法 | 可读性 | 简洁度 | 推荐场景 |
---|---|---|---|
临时变量 | ✅ 高 | ❌ 低 | 教学、调试、强调逻辑 |
Pair + apply | ✅ 高 | ✅ 中 | 生产环境,注重表达清晰 |
also{} 一行式 |
❌ 中等 | ✅ 高 | 工具类、DSL、偏好函数式风格 |
选择哪种方式取决于团队编码规范和个人偏好。但在生产项目中,建议优先考虑可读性和可维护性,避免过度追求“炫技”。
示例完整源码见:https://github.com/baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-7