// 第 3 周 – Go 中的数组和切片
// 运行：go run ./w03/arraybasics
package main

import (
	"fmt"
	"slices"
)

func main() {
	// 数组：大小是类型的一部分（[5]int 和 [6]int 是不同的类型）
	var a [5]int // 每个元素都是 0
	primes := [5]int{2, 3, 5, 7, 11}
	auto := [...]string{"a", "b", "c"} // 由编译器计算大小
	fmt.Println("a =", a, "primes =", primes, "auto =", auto, "len =", len(auto))

	// 直接访问 – O(1)
	primes[0] = 1
	fmt.Println("primes[4] =", primes[4])

	// 边界：常量下标越界是编译错误，变量下标越界是运行时错误（panic）
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Error:", r)
			rest()
		}
	}()
	i := 5
	primes[i] = 13 // panic：下标越界
}

func rest() {
	primes := [5]int{1, 3, 5, 7, 11}

	// 遍历
	sum := 0
	for _, p := range primes {
		sum += p
	}
	fmt.Println("sum =", sum)

	// 数组是值：赋值会复制它！
	cp := primes
	cp[1] = 100
	fmt.Println("primes[1] =", primes[1], ", cp[1] =", cp[1])

	// 切片：底层数组的一个大小可变的“视图”
	s := []int{5, 2, 9, 1}
	s = append(s, 7) // 扩展
	fmt.Println("slice:", s, "len =", len(s), "cap =", cap(s))

	alias := s // 切片赋值不会复制元素
	alias[0] = 0
	fmt.Println("after alias[0] = 0, s[0] =", s[0])

	dup := slices.Clone(s) // 真正的副本
	slices.Sort(dup)
	fmt.Println("sorted copy:", dup, ", original:", s)

	z := make([]int, 3, 10) // len 3,cap 10
	fmt.Println("make([]int, 3, 10):", z, len(z), cap(z))
}
