电话
400 9058 355
必须用 解引用才能修改原变量值,指针本身只是地址,不加 操作的是指针变量自身;传指针进函数需用 *p 修改目标值,nil 指针解引用会 panic,须判空;结构体嵌套指针字段需逐层检查并初始化;new(T) 仅得零值指针,&T{} 支持字段初始化;返回局部变量地址安全,因逃逸分析自动移至堆。
* 解引用才能改原变量的值Go 里指针本身只是个地址值,不加 * 就是在操作指针变量自己(比如赋新地址),不是在改它指向的值。常见错误是传指针进去却忘了 *,结果函数里看似“改了”,实际原变量毫发无伤。
实操要点:
&,修改目标值必须用 * 前缀*int,内部要写 *p = 42 才能改调用方的 int
nil 指针解引用会 panic,操作前建议判空(尤其从 map 或函数返回获取的指针)func increment(p *int) {
if p != nil { // 防 panic
*p++
}
}
x := 10
increment(&x)
// x 现在是 11
结构体指针字段(如 type User struct{ Profile *Profile })默认是 nil。直接写 u.Profile.Name = "Alice" 会 panic:assignment to entry in nil map / invalid memory address。
正确做法:
u.Profile != nil,再赋值u.Profile = &Profile{}
*map[string]int),需逐层判空 + 初始化type Config struct {
DB *DBConfig
}
c := &Config{}
if c.DB == nil {
c.DB = &DBConfig{Host: "localhost"}
}
c.DB.Port = 5432 // 安全
new() 和 &T{} 初始化指针的区别
两者都返回指向新分配零值的指针,但语义和适用场景不同:
new(T) 只能创建零值,返回 *T,适合简单类型或明确需要零值的场景&T{Field: val} 支持字段初始化,更常用,尤其结构体new() 初始化(它们本身是引用类型,new([]int) 返回的是 *[]int,不是你想要的可 append 的切片)// ✅ 正确
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 把这些底层细节藏好了,你只需盯紧 * 和 & 的配对,以及每个指针值是否真实指向有效内存。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...