下面这段代码输出什么?为什么?

package main

import (
    "fmt"
)

func main() {
    s1 := []int{1, 2, 3}
    s2 := s1[1:]
    s2[1] = 4
    fmt.Println(s1)
    s2 = append(s2, 5, 6, 7)
    fmt.Println(s1)
}
[1 2 4]
[1 2 4]

在线运行

切片共享底层数组

  1. 初始化切片 s1

    • s1 初始化为 []int{1, 2, 3},底层数组容量为 3。
  2. 创建新切片 s2

    • s2 := s1[1:] 创建了一个新切片,起始索引为 1,长度为 2(元素为 2, 3),容量为 2(原数组容量 3 减去起始索引 1)。
  3. 修改共享元素

    • s2[1] = 4 修改的是底层数组的索引 2(对应 s1[2]),因此 s1 变为 [1, 2, 4]
  4. append 触发扩容

    • 当执行 s2 = append(s2, 5, 6, 7) 时,原切片 s2 的容量已满(长度 2,容量 2)。
    • 追加操作触发底层数组扩容,系统分配新数组,原数据被复制到新数组,后续修改不再影响 s1 的底层数组。
  5. 两次输出结果一致

    • 第一次 fmt.Println(s1) 输出 [1 2 4],反映共享数组的修改。
    • 第二次输出时,s2 的扩容已使其脱离原数组,s1 仍保持为 [1 2 4]