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 作用域函数,在其上下文中通过 firstsecond 访问原值并反向赋值。

💡 小贴士: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 } 的含义是:
    1. 先保存当前 b 的值(用于后续返回)
    2. 执行 { b = a } —— 把 a 的值赋给 b
    3. 最后返回原来的 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


原始标题:Swap Function in Kotlin