【2024-10-30】golang切片构建、扩容的两段代码

59 阅读1分钟

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看不到)。