Golang中部分切片交换的实现方法
Golang中部分切片交换的实现方法
package main
import "fmt"
func main() {
var i int
X := make([]byte, 64)
for i = 0; i < 32; i++ {
X[i] = 0; X[32+i] = 1;
}
fmt.Println(X)
//OPTION_1--------------------------------------------------
L := make([]byte, 32)
R := make([]byte, 32)
for i = 0; i < 32; i++ {
L[i] = X[i]; R[i] = X[32+i];
}
//OPTION_2--------------------------------------------------
// L := X[0:32]
// R := X[32:64]
//--------------------------------------------------
fmt.Println(L)
fmt.Println(R)
//COPYING--------------------------------------------------
/*
for i = 0; i < 32; i++ {
X[i] = R[i]
X[32+i] = L[i]
}
*/
copy(X[0:32], R[:])
copy(X[32:64], L[:])
fmt.Println(X)
}
各位大师好, 这是一个Go语言初学者的问题。请阅读这个使用两个32元素数组交换64元素数组的代码。我使用了两种方法(选项),一种可行,另一种不可行。请告诉我哪里出错了,以及这门语言中真正的概念是什么。 谢谢。
更多关于Golang中部分切片交换的实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
切片是引用类型。
L 是指向 X[0:32] 的切片指针
R 是指向 X[32:64] 的切片指针
当你执行第一次复制 copy(X[0:32], R[:])
L 现在被设置为 R(指针)
第二次复制使用更新后的 L 来复制到 X[32:64]
因此你会看到全部都是 1 [11111…]
更多关于Golang中部分切片交换的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,切片是引用类型,理解切片与底层数组的关系是关键。你的代码问题在于切片共享底层数组,这导致了意外的修改。
问题分析
在OPTION_2中:
L := X[0:32]
R := X[32:64]
L和R与X共享同一个底层数组。当你执行:
copy(X[0:32], R[:])
copy(X[32:64], L[:])
第一次copy(X[0:32], R[:])将R的内容复制到X的前半部分,但由于L指向X的前半部分,L的内容也被修改了。然后第二次复制时,你实际上是在用已经改变的L来覆盖X的后半部分。
正确的解决方案
方案1:使用临时切片(推荐)
package main
import "fmt"
func main() {
X := make([]byte, 64)
for i := 0; i < 32; i++ {
X[i] = 0
X[32+i] = 1
}
fmt.Println("Original:", X)
// 创建临时切片来保存原始数据
temp := make([]byte, 64)
copy(temp, X)
// 执行交换
copy(X[0:32], temp[32:64])
copy(X[32:64], temp[0:32])
fmt.Println("After swap:", X)
}
方案2:使用显式循环
func swapSlices(X []byte) {
for i := 0; i < 32; i++ {
X[i], X[32+i] = X[32+i], X[i]
}
}
方案3:使用append创建独立切片
L := append([]byte{}, X[0:32]...)
R := append([]byte{}, X[32:64]...)
copy(X[0:32], R)
copy(X[32:64], L)
核心概念
切片包含三个组件:
- 指针:指向底层数组
- 长度:切片中元素的数量
- 容量:从切片开始位置到底层数组末尾的元素数量
当你创建切片时:
slice1 := arr[0:5] // slice1与arr共享底层数组
slice2 := make([]int, 5) // slice2有独立的底层数组
理解这个区别可以避免很多常见的切片操作错误。

