通八洲科技

如何使用Golang实现指针与值类型区别_Golang传值与传引用示例

日期:2025-12-31 00:00 / 作者:P粉602998670
Go只有传值,指针传的是地址副本;结构体需传指针才能修改原值;切片/map/channel是含指针的值类型;nil指针解引用会panic;关键在所传值是否指向原始数据。

Go 里没有“传引用”,只有“传值”——但指针变量的值是地址

Go 语言中所有参数传递都是值传递,func f(x int)func f(p *int) 的区别不在于“传引用”或“传值”,而在于你传进去的“值”本身是什么:一个是整数副本,一个是内存地址副本。误以为 Go 支持引用传递,是初学者踩坑最频繁的认知偏差。

修改结构体字段时,为什么传指针才生效?

因为结构体默认按值传递,函数内操作的是副本;传 *struct 后,你拿到的是原结构体地址,解引用 (*s).Field 或简写 s.Field 就能改原始内存。

切片、map、channel 是“引用类型”?不,它们是含指针的描述符

[]intmap[string]intchan int 本身是值类型,但它们底层结构包含指向底层数组/哈希表/队列的指针。所以:

常见误用:对 nil 指针解引用 panic

*T 并不保证它非 nil;没初始化的指针变量值是 nil,直接解引用会触发 panic: runtime error: invalid memory address or nil pointer dereference

func printName(u *User) {
    // ❌ 危险!未检查 u 是否为 nil
    fmt.Println(u.Name)

    // ✅ 应先判断
    if u == nil {
        fmt.Println("user is nil")
        return
    }
    fmt.Println(u.Name)
}

接口值(interface{})和指针一样,也可能为 nil;但空接口变量本身非 nil,不代表它装的动态值非 nil —— 这点容易混淆,需格外注意。

真正关键的不是“传值还是传引用”,而是“你传的那个值,是否指向可修改的原始数据”。盯住变量的类型本质(int vs *int vs []int),比记口诀管用得多。