1.9 指针
指针基础
go
package main
import "fmt"
func main() {
// 指针声明
var p *int // 指向 int 的指针,值为 nil
x := 42
p = &x // p 指向 x
fmt.Println("x 的值:", x) // 42
fmt.Println("x 的地址:", &x) // 0x...
fmt.Println("p 的值:", p) // 0x...
fmt.Println("p 指向的值:", *p) // 42
// 修改指针指向的值
*p = 100
fmt.Println("x:", x) // 100
// 指针的指针
pp := &p
fmt.Println("**pp:", **pp) // 100
}new 和 make 的区别
go
package main
import "fmt"
func main() {
// new
// new(T): 分配内存,返回 *T,值为零值
p1 := new(int) // *int, 值为 0
p2 := new(string) // *string, 值为 ""
p3 := new([]int) // *[]int, 值为 nil
fmt.Println(*p1) // 0
fmt.Println(*p2) // 空字符串
// make
// make(T, args): 仅用于 slice, map, channel
// 返回 T (不是指针)
s := make([]int, 5) // []int, 长度 5
m := make(map[string]int) // map[string]int
ch := make(chan int, 1) // chan int
fmt.Println(s) // [0 0 0 0 0]
fmt.Println(m) // map[]
}指针与函数参数传递
go
package main
import "fmt"
func main() {
// 值传递
x := 10
modifyValue(x)
fmt.Println("值传递后:", x) // 10 (不变)
// 指针传递
modifyPointer(&x)
fmt.Println("指针传递后:", x) // 100 (改变)
// 切片/Map 是引用语义
s := []int{1, 2, 3}
modifySlice(s)
fmt.Println("切片修改后:", s) // [100 2 3]
}
func modifyValue(x int) {
x = 100
}
func modifyPointer(p *int) {
*p = 100
}
func modifySlice(s []int) {
s[0] = 100
}指针的安全性
go
package main
import "fmt"
func main() {
// Go 指针的安全特性:
// 1. 不能进行指针算术运算
// 2. 指针不能转换为其他类型指针 (需要 unsafe)
// 3. 空指针检查
// 4. 野指针由 GC 处理
var p *int
if p == nil {
fmt.Println("p 是空指针")
}
// 安全使用准则
// 1. 只在必要时使用指针
// 2. 始终检查 nil
// 3. 注意并发访问
}