交换两个变量的值
交换两个变量的值是很常见的操作,通常的做法都是借个临时变量来完成交换:
fun foo() {
var a = 0
var b = 1
val temp = a
a = b
b = temp
}
这种写法一方面繁琐,另一方面还需要增加额外的临时变量。稍微逼格化一下:
fun foo() {
var a = 0
var b = 1
a = b.apply { b = a }
}
但是,作为一个有志青年,在优化道路上永无止尽的我们显然还是不满足。联想到 kotlin 有个中缀操作符,要是我们自定义一个 swap
操作符那该多好啊,这样一来代码就简化多了:
fun foo() {
var a = 0
var b = 1
a swap b
}
至此,仿佛已经看见了胜利的曙光。但理想是美好的,现实却是残酷的。事实是 kotlin 没有任何办法实现 swap
中缀操作符!
是的,你没有看错,kotlin 无法实现 swap
中缀操作符。不信?来我们尝试一下,假如有 swap
中缀操作符,那么大概应该是这个样子的:
public infix fun Number.swap(other: Number): Unit {
this = other.apply { other = this }
}
然而,这段代码直接编译告警,根本无法运行。中缀操作的两端都是 val 值,无法在 swap 函数里对其重新赋值。
有的朋友会纳闷儿,我们明明是需要对变量进行交换,怎么成了对 Number 类进行中缀操作呢?这是因为 kotlin 没有变量类型的类,如果有,它大概会叫做指针。
还记得这个经典的 java 陷阱吗:
public static final void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
由于 java 函数是值传递,而非引用传递,上面这段代码属于自欺欺人。这一切皆是源自 java 没有指针。
所以,最后,正确的交换方式是?