如果没看golang切片的第一篇总结博客 golang的切片使用总结一-CSDN博客 ,请先浏览之
s := make([]int, 10, 12)
v := s[10]
fmt.Printf("v:%v", v)
打印结果:
panic: runtime error: index out of range [10] with length 10
goroutine 1 [running]:
main.main()
结论:capacity(容量)是物理意义上的,空间归切片s所有;但len(长度)是逻辑意义上的,访问元素时是根据逻辑意义为准,因为s[10]是越界访问
s := make([]int, 10, 12)
s1 := s[8:]
s1 = append(s1, []int{10, 11, 12}...)
v := s[10]
fmt.Printf("v:%v", v)
打印结果:
panic: runtime error: index out of range [10] with length 10
goroutine 1 [running]:
main.main()
结论:虽然s1从s截取得到,二者共享同一块内存数据。但是后面的s1 = append(s1)操作会让s1发生扩容,s1扩容后就跟s完全分开了,内存完全独立。所以,s还是原来的len为10,访问s[10]会发生panic
func main() {
s := make([]int, 10, 12)
s1 := s[8:]
changeSlice(s1)
fmt.Printf("s: %v", s)
}func changeSlice(s1 []int) {
s1[0] = -1
}
打印结果:s: [0 0 0 0 0 0 0 0 -1 0]
结论:切片s1是从切片s截取得到,传入函数后,由于切片是引用传递,函数内的s1[0]和函数外的s[8]是同一个元素,所以原切片s会被修改
举例12:
func main() {
s := make([]int, 10, 12)
s1 := s[8:]
changeSlice(s1)
fmt.Printf("s:%v, len of s:%v, cap of s:%v \n", s, len(s), cap(s))
fmt.Printf("s1:%v, len of s1:%v, cap of s1:%v \n", s1, len(s1), cap(s1))}
func changeSlice(s1 []int) {
s1[0] = -1
}
打印结果:
s:[0 0 0 0 0 0 0 0 -1 0], len of s:10, cap of s:12
s1:[-1 0], len of s1:2, cap of s1:4
结论:虽然切片是引用传递,但指的是元素数据存储为引用,切片参数仍然是不同的slice header。所以函数changeSlice()内的s1和函数外的s1指向的是同一块数据,修改生效。但是函数changeSlice()内的s1和函数外的s1是两个不同的slice header,函数