go版本为1.22,机器为macbook pro 2021年14寸m1pro,系统为14.4.1
go version go1.22.2 darwin/arm64
第一段代码
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := slice[2:5]
s2 := s1[2:6:7]
s2 = append(s2, 100)
s2 = append(s2, 200)
s1[2] = 20
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(slice)
}
输出如下:
[2 3 20]
[4 5 6 7 100 200]
[0 1 2 3 20 5 6 7 100 9]
第二段代码
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := slice[2:5]
s2 := s1[2:6]
s2 = append(s2, 100)
s1[2] = 20
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(slice)
}
输出如下:
[2 3 20]
[20 5 6 7 100]
[0 1 2 3 20 5 6 7 100 9]
分析
1.做切片时,第三个参数控制capacity
s1[2:6:7]里的7
- length为6-2=4
- capacity为7-2=5
2.做切片时,会指向原来的内存空间
在第二段代码修改s1[2]=20时,s2和slice都会被修改
3.在未发生扩容时,append会修改原内存空间
也是因为指向原来的内存空间,append直接修改了后一段内存空间的内容。
第二段代码s2 = append(s2, 100)时,slice可以看到。
4.在发生扩容时,会指向新的内存空间,不会修改原内存空间。
做完切片s2的length是4,capacity为5。
第一段代码:
s2第一次做append时,未发生扩容(length为5,capacity为5),直接修改原内存空间(slice可以看到)。
s2第二次做append时,发生了扩容,在新的内存空间做追加(slice看不到)。