一般可以用异或的方式不借助第三方值来交换数字,类似如下
func main() { swaps := func(k int, b int) (x, y int) { k ^= b b ^= k k ^= b return k, b } x,y :=swaps(5,6) fmt.Printf("结果为: %d,%d", x, y) }
结果为: 6,5
但是今天在数组交换中装逼失败,比如如下输出的会是[0,3,1] ,而不是[1,3,1]
func main() { arr := [3]int{1,3,1} swaps := func(arr *[3]int,k int, b int) { arr[k] ^= arr[b] arr[b] ^= arr[k] arr[k] ^= arr[b] } swaps(&arr,0,0) fmt.Println(arr) }
这是因为arr[k]和arr[b]索引相同时指向同一块内存。arr[k] ^ arr[b] 的结果则肯定为0,此时arr[k]也就是arr[b]都为0 ,后续的操作也就全部都是 0^0 结果自然为0.例如上面的交换数据函数改为同一块内存的两个参数值
func main() { swaps := func(k *int, b *int) (x, y int) { *k ^= *b *b ^= *k *k ^= *b return *k, *b } k := 5 s := &k fmt.Printf("内存地址分别为: %p,%p ", &k, s) x,y :=swaps(&k,s) fmt.Printf("结果为: %d,%d ", x, y) }
内存地址分别为: 0xc00000a0b8,0xc00000a0b8 结果为: 0,0
可以看到内存地址一致时会变为0
所以要用异或来交换两个值记得判断是否为同一块内存,例如在数组中就可以加上 索引k != b的判断,即如下即可
func main() { arr := [3]int{1,3,1} swaps := func(arr *[3]int,k int, b int) { if k != b { arr[k] ^= arr[b] arr[b] ^= arr[k] arr[k] ^= arr[b] } } swaps(&arr,0,0) fmt.Println(arr) }