保存为 main.go,执行 go run main.go。地址值每次运行不同,但“扩容前相同、扩容后分离”的关系不变。
完整 Go 示例
package main
import "fmt"
func main() {
base := make([]int, 2, 4)
base[0], base[1] = 10, 20
alias := base
fmt.Printf("初始 base=%v len=%d cap=%d addr=%p\n",
base, len(base), cap(base), &base[0])
fmt.Printf("初始 alias=%v len=%d cap=%d addr=%p\n",
alias, len(alias), cap(alias), &alias[0])
// 容量够:仍使用同一底层数组。
base = append(base, 30)
alias[0] = 99
fmt.Println("未扩容后 base =", base) // [99 20 30]
// 一次追加到超过 cap:触发扩容并复制。
base = append(base, 40, 50)
base[0] = 777
fmt.Printf("扩容 base=%v len=%d cap=%d addr=%p\n",
base, len(base), cap(base), &base[0])
fmt.Printf("旧的 alias=%v len=%d cap=%d addr=%p\n",
alias, len(alias), cap(alias), &alias[0])
// 完整切片表达式:限制 cap,强制下一次 append 分离。
parent := []int{1, 2, 3, 4}
child := parent[:2:2]
child = append(child, 100)
fmt.Println("parent =", parent) // [1 2 3 4]
fmt.Println("child =", child) // [1 2 100]
}
观察重点:地址只用于验证底层数组是否变化,不要在业务逻辑里依赖地址或某次运行的具体 cap 数字。