【踩了一个坑】为什么 golang struct 中的 slice 无法原子赋值

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


有这样一个结构体:

type MySt struct{
    Field []byte
}

我在数组排序中想要交换值:

func Swap(arr []MySt, i,j int){
    arr[i], arr[j] = arr[j], arr[i]
}

我猜测,就算其成员 Field 是引用类型,但是引用的指针也会交换,应该是没问题的。
实际测试这里复制错误了。

于是我换个写法:

func Swap(arr []MySt, i,j int){
    arr[i].Field, arr[j].Field = arr[j].Field, arr[i].Field
}

上面的代码仍然是不行。
猜测是编译期产生的代码不是类似 memcpy() 这种,而是逐个成员去交换,交换到指针这里时,无法做到原子的交换,从而出了问题。

改成下面的方法,终于对了:

func Swap(arr []MySt, i,j int){
    arr[i].Field, arr[j].Field = swapSlice(arr[j].Field, arr[i].Field)
}

func swapSlice(a, b []byte) ([]byte, []byte) {
	return b, a
}

仍然无法理解我为社么错了,求指教。

posted on 2024-01-20 08:14  ahfuzhang  阅读(14)  评论(0编辑  收藏  举报