在Go语言中,切片(slice)是一个引用类型,它包含了一个指向底层数组的指针、切片的长度和容量。当你对切片进行append
操作时,可能会遇到修改一个切片影响另一个切片的情况。这种情况通常发生在两个切片共享同一个底层数组时。
共享底层数组:
slice[start:end]
),新切片和原切片会共享同一个底层数组。append
操作),并且这个操作没有触发底层数组的重新分配,那么另一个切片也会受到影响,因为它们共享同一个底层数组。append
操作的底层数组重新分配:
append
操作导致切片的长度超过其容量时,Go会重新分配一个新的底层数组,并将原数组的内容复制到新数组中。此时,新切片和原切片将不再共享同一个底层数组。append
操作没有触发重新分配,那么新切片和原切片仍然共享同一个底层数组,修改一个切片会影响另一个。package main
import "fmt"
func main() {
// 创建一个切片
slice1 := []int{1, 2, 3, 4, 5}
// 创建一个新切片,共享同一个底层数组
slice2 := slice1[1:3]
// 修改slice2
slice2[0] = 99
// 输出slice1和slice2
fmt.Println("slice1:", slice1) // 输出: slice1: [1 99 3 4 5]
fmt.Println("slice2:", slice2) // 输出: slice2: [99 3]
// 对slice2进行append操作,未触发重新分配
slice2 = append(slice2, 100)
// 输出slice1和slice2
fmt.Println("slice1:", slice1) // 输出: slice1: [1 99 3 100 5]
fmt.Println("slice2:", slice2) // 输出: slice2: [99 3 100]
// 对slice2进行append操作,触发重新分配
slice2 = append(slice2, 200, 300)
// 输出slice1和slice2
fmt.Println("slice1:", slice1) // 输出: slice1: [1 99 3 100 5]
fmt.Println("slice2:", slice2) // 输出: slice2: [99 3 100 200 300]
}
如果你不希望两个切片共享同一个底层数组,可以通过copy
函数或append
操作来创建一个新的切片,确保它们使用不同的底层数组。
package main
import "fmt"
func main() {
// 创建一个切片
slice1 := []int{1, 2, 3, 4, 5}
// 创建一个新切片,不共享同一个底层数组
slice2 := make([]int, len(slice1[1:3]))
copy(slice2, slice1[1:3])
// 修改slice2
slice2[0] = 99
// 输出slice1和slice2
fmt.Println("slice1:", slice1) // 输出: slice1: [1 2 3 4 5]
fmt.Println("slice2:", slice2) // 输出: slice2: [99 3]
}
append
操作可能会触发底层数组的重新分配,导致切片不再共享同一个底层数组。copy
函数或append
操作来创建新的切片,确保它们使用不同的底层数组。