Skip to content

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. 注意并发访问
}