在Golang开发中,指针解引用操作如果使用不当,很容易造成编译不通过或者运行时的panic。了解常见的错误场景,可以帮助我们在编码阶段就规避风险,写出更健壮的程序。

一、对nil指针直接解引用
最典型的错误是声明了一个指针变量,但没有为其分配有效的内存地址,就直接通过*ptr取值。此时指针的值为nil,解引用会触发运行时panic。
package main
import "fmt"
func main() {
var p *int
// 下面这行会 panic: runtime error: invalid memory address or nil pointer dereference
// fmt.Println(*p)
// 正确做法:先分配内存
p = new(int)
*p = 10
fmt.Println(*p)
}
二、函数返回局部变量地址的误解
有些开发者担心返回局部变量地址会失效,实际上Golang的逃逸分析会让局部变量在函数结束后继续存活。但如果是返回了未初始化的指针字段,依然可能解引用失败。
package main
import "fmt"
type User struct {
name *string
}
func getUser() User {
return User{}
}
func main() {
u := getUser()
// u.name为nil,解引用会panic
// fmt.Println(*u.name)
s := "tom"
u.name = &s
fmt.Println(*u.name)
}
三、接口断言为指针得到nil
当从一个接口类型断言出指针时,如果原接口底层值并不是该指针类型,断言结果指针为nil,直接解引用同样会报错。
package main
import "fmt"
func main() {
var i interface{} = 100
p, ok := i.(*int)
if !ok {
fmt.Println("断言失败,p为nil")
}
// 此时p为nil,不能解引用
// fmt.Println(*p)
}
四、多重指针层级处理错误
在使用指向指针的指针时,如果少写了一层解引用,或者层级关系混乱,也会导致取值错误甚至编译失败。
package main
import "fmt"
func main() {
x := 5
p := &x
pp := &p
// 需要两次解引用
fmt.Println(**pp)
// 如果只写一次,得到的是*p的地址,不是值
fmt.Println(*pp)
}
五、总结
以上场景说明,Golang指针解引用失败大多源于指针未指向有效地址或类型断言不当。编码时应养成初始化指针、断言后判空、理清指针层级的习惯,从而减少低级错误。