golang的切片使用总结二

如果没看golang切片的第一篇总结博客 golang的切片使用总结一-CSDN博客 ,请先浏览之

举例9:make([]int, a, b)后访问下标a的元素

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]是越界访问

举例10:make([]int, a, b)后截取新切片,再append新切片

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

举例11:切片在函数中是值传递还是引用传递

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,函数

你可能感兴趣的:(Go语言,golang切片使用总结)