package main import "fmt" type Student struct { Name string Age int } // 传入整数副本,只修改函数内部的 value。 func changeValue(value int) { value = 100 } // 指针参数本身也按值传递,但它指向调用方的整数。 // 返回 bool 表示是否成功,避免解引用 nil 指针。 func changeByPointer(value *int) bool { if value == nil { return false } *value = 100 return true } // 给参数指针重新赋值,不会改变调用方指针本身。 func redirect(value *int) { local := 999 value = &local } // 结构体指针可以直接用点号访问字段,无需 C 风格的 ->。 func birthday(student *Student) bool { if student == nil { return false } student.Age++ // 等价于 (*student).Age++。 return true } func main() { // 1. & 取得变量地址;*int 表示“指向 int 的指针类型”。 fmt.Println("=== 取地址与解引用 ===") number := 10 var pointer *int = &number fmt.Printf("number 的值:%d\n", number) fmt.Printf("指针类型:%T,是否指向 number:%t\n", pointer, pointer == &number) fmt.Printf("通过 *pointer 读取:%d\n", *pointer) // 2. *pointer 在表达式中表示访问所指向的变量。 *pointer = 20 fmt.Printf("通过指针修改后,number:%d\n", number) // 3. 对比普通参数与指针参数。 fmt.Println("\n=== 函数修改原变量 ===") changeValue(number) fmt.Printf("普通参数调用后:%d\n", number) ok := changeByPointer(&number) fmt.Printf("指针参数调用后:%d,成功:%t\n", number, ok) // 4. 复制指针仍指向同一变量;改指向和改内容是两回事。 fmt.Println("\n=== 指针复制与重新指向 ===") alias := pointer *alias = 30 fmt.Printf("通过 alias 修改后,number:%d\n", number) redirect(pointer) fmt.Printf("函数内重新指向后,原指针仍指向 number:%t\n", pointer == &number) // 5. 指针零值是 nil,没有指向有效变量时不能解引用。 fmt.Println("\n=== nil 指针 ===") var empty *int fmt.Printf("空指针为 nil:%t\n", empty == nil) fmt.Printf("传入 nil,修改成功:%t\n", changeByPointer(empty)) // fmt.Println(*empty) // 取消注释会导致运行时 panic。 // 6. 结合结构体:通过指针修改原学生的年龄。 fmt.Println("\n=== 结构体指针 ===") student := Student{Name: "小朱", Age: 20} birthday(&student) fmt.Printf("%s 过生日后,年龄:%d\n", student.Name, student.Age) // 7. new(int) 返回指向一个零值 int 的指针,不是 nil。 fmt.Println("\n=== new 创建指针 ===") created := new(int) fmt.Printf("指针为 nil:%t,初始值:%d\n", created == nil, *created) *created = 42 fmt.Printf("修改后的值:%d\n", *created) }