定义切片
var slice []int //一个无长度的数组
slice := []int{1,2,3} //初始化切片,len和cap为3
slice := make([]int, 3, 4)。//初始化一个len为3 cap为4的切片
arr := [4]int{1,2,3,4}
slice := arr[:3] // 此切片len和cap为3,值为{1,2,3}
slice底层机制
当slice作为参数时,go会对传入的slice进行复制然后传入函数
func changeSlice(a []int) {
a[3] = 6
}
func main() {
arr := [4]int{1,2,3,4}
slice := arr[:4]
changeSlice(slice)
fmt.Println(arr)
}
//结果:{1,2,3,6}
在上面的例子中,changeSlice函数改变了传入切片的值,但是arr的值却改变了。说明slice以及传入的参数底层都指向arr的内存空间。
只有当slice的容超出底层数组的长度时,slice指向的内存空间才会改变,此时slice会指向一块新开辟的数组。
func changeSlice(a []int) {
a = append(a, 6) //这里因为切片的长度超出了arr数组的长度,切片a会指向一块新的数组
a[3] = 5
fmt.Println(a)
}
func main() {
arr := [4]int{1,2,3,4}
slice := arr[:4]
changeSlice(slice)
fmt.Println(arr, slice)
}
//结果:{1,2,3,5,6}, {1,2,3,4}, {1,2,3,4}
- 注意:如果切片的长度没有超出底层数组的长度,则使用append会改变底层数组的值:
func changeSlice(a []int) {
a = append(a, 6) //这里因为切片的长度没有超出arr的长度
a[3] = 5
fmt.Println(a)
}
func main() {
arr := [5]int{1,2,3,4,5}
slice := arr[:3]
changeSlice(slice)
fmt.Println(arr, slice)
}
//结果:{1,2,3,5,6}, {1,2,3,5,6}, {1,2,3,5}
如果想要给切片开辟一块新空间还可以使用以下方法:
arr := [5]int{1, 2, 3, 4, 5}
slice2 := append([]int{}, arr[:4]...)
arr[3] = 6
fmt.Println(slice2)
//结果 {1,2,3,4}
用 append(空切片, 目标切片) 的方法可以使切片指向一个新开辟的数组空间。这样slice的值就不会受到原数组的影响了。