切片是数组或另一个切片之上的数据结构。 我们将源数组或切片称为基础数组。 通过切片,可访问整个基础数组,也可仅访问部分元素。
切片只有 3 个组件:
- 指向基础数组中第一个可访问元素的指针。 此元素不一定是数组的第一个元素
array[0]
。 - 切片的长度。 切片中的元素数目。
- 切片的容量。 切片开头与基础数组结束之间的元素数目。
下述代码确认切片指向数组,而你在切片中所做的每个更改都会影响基础数组。
package mainimport "fmt"func main() {letters := []string{"A", "B", "C", "D", "E"}fmt.Println("Before", letters)slice1 := letters[0:2]slice2 := letters[1:4]slice1[1] = "Z"fmt.Println("After", letters)fmt.Println("Slice2", slice2)
}
输出
Before [A B C D E]
After [A Z C D E]
Slice2 [Z C D]
可在输出中看到字母 B 已替换为 Z,它会影响指向 letters 数组的每个切片。
若要解决此问题,你需要创建一个切片副本,它会在后台生成新的基础数组。 可以使用以下代码:
package mainimport "fmt"func main() {letters := []string{"A", "B", "C", "D", "E"}fmt.Println("Before", letters)slice1 := letters[0:2]slice2 := make([]string, 3)copy(slice2, letters[1:4])slice1[1] = "Z"fmt.Println("After", letters)fmt.Println("Slice2", slice2)
}
输出
Before [A B C D E]
After [A Z C D E]
Slice2 [B C D]
此时 slice1 中的更改并未影响新的 slice2。