贝利信息

Golang指针如何修改变量值_通过指针操作变量技巧

日期:2026-01-21 00:00 / 作者:P粉602998670
必须用 解引用才能修改原变量值,指针本身只是地址,不加 操作的是指针变量自身;传指针进函数需用 *p 修改目标值,nil 指针解引用会 panic,须判空;结构体嵌套指针字段需逐层检查并初始化;new(T) 仅得零值指针,&T{} 支持字段初始化;返回局部变量地址安全,因逃逸分析自动移至堆。

* 解引用才能改原变量的值

Go 里指针本身只是个地址值,不加 * 就是在操作指针变量自己(比如赋新地址),不是在改它指向的值。常见错误是传指针进去却忘了 *,结果函数里看似“改了”,实际原变量毫发无伤。

实操要点:

func increment(p *int) {
    if p != nil { // 防 panic
        *p++
    }
}
x := 10
increment(&x)
// x 现在是 1

1

结构体指针字段赋值要注意是否已初始化

结构体指针字段(如 type User struct{ Profile *Profile })默认是 nil。直接写 u.Profile.Name = "Alice" 会 panic:assignment to entry in nil map / invalid memory address。

正确做法:

type Config struct {
    DB *DBConfig
}
c := &Config{}
if c.DB == nil {
    c.DB = &DBConfig{Host: "localhost"}
}
c.DB.Port = 5432 // 安全

new()&T{} 初始化指针的区别

两者都返回指向新分配零值的指针,但语义和适用场景不同:

// ✅ 正确
p1 := new(int)      // *int,值为 0
p2 := &User{Name: "Tom"} // *User,Name 已赋值

// ❌ 错误用法
s := new([]string)  // 得到 **[]string,不是能 append 的切片
// 应该用:
s := make([]string, 0)

函数返回局部变量地址是安全的

Go 编译器会自动做逃逸分析,把本该分配在栈上的变量提升到堆上,所以返回局部变量地址不会导致悬垂指针。这点和 C/C++ 完全不同,不必手动 malloc 或担心生命周期。

但要注意:

func getCounter() *int {
    x := 0 // x 会被自动移到堆上
    return &x
}
p := getCounter()
*p = 100 // 完全合法
真正容易出错的地方不在语法,而在忘记解引用、忽略 nil 检查、或误以为返回局部变量地址是危险操作——Go 把这些底层细节藏好了,你只需盯紧 *& 的配对,以及每个指针值是否真实指向有效内存。