切片
切片是数组或另一个切片之上的数据结构。 我们将源数组或切片称为基础数组。 通过切片,可访问整个基础数组,也可仅访问部分元素。
切片只有 3 个组件:
- 指向基础数组中第一个可访问元素的指针。 此元素不一定是数组的第一个元素
array[0]
。 - 切片的长度。 切片中的元素数目。
- 切片的容量。 切片开头与基础数组结束之间的元素数目。
下述代码确认切片指向数组,而你在切片中所做的每个更改都会影响基础数组。
package main
import "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 main
import "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。
练习题
下面的代码有什么问题?
func main() {
fmt.Println([...]int{1} == [2]int{1})
fmt.Println([]int{1} == []int{1})
}
参考答案及解析:
答案1
有两处错误
- go 中不同类型是不能比较的,而数组长度是数组类型的一部分,所以
[...]int{1}
和[2]int{1}
是两种不同的类型,不能比较; - 切片是不能比较的;
答案2
go 中不同类型是不能比较的,而数组长度是数组类型的一部分,所以 [...]int{1}
和 [2]int{1}
是两种不同的类型,不能比较; 切片是不能比较的;
数据是可以比较的, 但是类型和长度必须一致