package main

import "fmt"

func main() {
	// ========== 1. 基本类型 ==========
	var a int = 42
	var b float64 = 3.14
	var c bool = true
	var d string = "Hello, Go!"

	fmt.Println("基本类型:")
	fmt.Printf("int: %d\n", a)
	fmt.Printf("float64: %.2f\n", b)
	fmt.Printf("bool: %t\n", c)
	fmt.Printf("string: %s\n", d)

	// ========== 2. 变量声明方式 ==========
	// 方式1：var 声明（可带或不带初始值）
	var x int
	x = 100
	var y = 200 // 类型自动推导

	// 方式2：批量声明
	var (
		name    = "Liu"
		age     = 30
		height  = 175.5
		isAdmin = true
	)

	fmt.Println("\n变量声明:")
	fmt.Println("x =", x, ", y =", y)
	fmt.Println("name:", name, "age:", age, "height:", height, "isAdmin:", isAdmin)

	// ========== 3. := 简短声明（仅在函数内部可用）==========
	z := 999              // 自动推导为 int
	message := "Use := !" // 自动推导为 string
	fmt.Println("\n简短声明 (:=):")
	fmt.Println("z =", z, ", message =", message)

	// 注意：:= 必须至少声明一个新变量
	// 下面这行会报错：no new variables on left side of :=
	//z := 888 // ❌ 错误！

	// 但可以这样混合新旧变量：
	w, z := "new", 888 // w 是新的，z 是重新赋值（shadowing）
	fmt.Println("w =", w, ", z =", z)

	// ========== 4. 指针 ==========
	p := &a // p 是指向 a 的指针（*int 类型）
	fmt.Println("\n指针:")
	fmt.Printf("a 的值: %d\n", a)
	fmt.Printf("a 的地址: %p\n", &a)
	fmt.Printf("p 的值（即 a 的地址）: %p\n", p)
	fmt.Printf("*p（解引用）: %d\n", *p)

	*p = 1000 // 通过指针修改 a 的值
	fmt.Println("修改后 a =", a)

	// ========== 5. new vs make ==========
	// new(T) → 分配零值内存，返回 *T
	ptrInt := new(int) // *int，值为 0
	*ptrInt = 42
	fmt.Println("\nnew(int):", *ptrInt)

	// make 仅用于 slice, map, chan —— 返回初始化后的 T（不是指针！）
	s := make([]int, 3)       // 长度为3的 slice，元素为 [0 0 0]
	m := make(map[string]int) // 空 map
	ch := make(chan int, 2)   // 缓冲通道

	s[0] = 10
	m["count"] = 1
	ch <- 100

	fmt.Println("make(slice):", s)
	fmt.Println("make(map):", m)
	fmt.Println("make(chan) 示例（略去接收）")

	// ⚠️ 不能对 slice/map/chan 使用 new！
	// bad := new([]int) // 这是一个 *[]int，但底层数组未初始化，不能直接用！
}
