如何使用Golang理解指针初始化_Golang创建和赋值指针变量

14次阅读

go指针变量默认初始化为nil,需用&取地址或new()分配内存才能安全使用;禁止对字面量取地址;解引用nil指针会panic。

如何使用Golang理解指针初始化_Golang创建和赋值指针变量

怎么声明并初始化一个指针变量

Go 中不能直接声明未初始化的指针变量为 nil 以外的值,所有指针变量默认初始值都是 nil。要让它指向有效内存,必须用取地址符 & 显式获取某个变量的地址,或者用 new() 分配零值内存。

  • var p *intp*int 类型,值为 nil,此时解引用会 panic
  • var x int = 42; p := &x → 安全:p 指向上变量 x
  • p := new(int) → 返回指向新分配的零值 int 的指针(等价于 new(int) == &zero_int

为什么不能对字面量直接取地址

Go 禁止对临时值(如字面量、函数返回值)取地址,因为它们没有确定的内存生命周期。比如 &42&(x + y) 都会编译报错:cannot take the address of ...

  • 错误写法:p := &42 → 编译失败
  • 正确写法:先赋给变量再取址 —— val := 42; p := &val
  • 或用 new() 替代:p := new(int); *p = 42

new() 和 & 变量的区别在哪

两者都返回指针,但语义和内存位置不同:&x 指向已有变量(可能在或逃逸到),new(T) 总是在堆上分配零值 T 并返回其地址。

func example() {     // &x:x 可能被优化到栈上(除非逃逸)     x := 100     p1 := &x      // new(int):明确在堆分配,返回 *int 指向零值(即 0)     p2 := new(int) // 等价于:p2 := &int(0)      fmt.Println(*p1, *p2) // 输出:100 0 }
  • new(T) 只能创建零值,无法指定初始内容
  • 若需非零初始值,必须先 new(T) 再赋值,或用 &T{...} 复合字面量(适用于结构体等)
  • 对基本类型(如 intString),&T{v} 不合法,只能用变量 + &new() + 赋值

常见 panic 场景:解引用 nil 指针

这是 Go 中最典型的指针错误。只要对值为 nil 的指针执行 *p 操作,运行时就 panic:invalid memory address or nil pointer dereference

立即学习go语言免费学习笔记(深入)”;

  • 典型误用:var p *string; fmt.Println(*p) → 直接 panic
  • 安全习惯:使用前检查是否为 nil,尤其在函数参数或结构体字段中接收指针时
  • 结构体中嵌入指针字段(如 type User Struct { Name *string }),jsON 反序列化后该字段可能为 nil,直接 *u.Name 很危险

指针本身不复杂,难的是判断“它到底有没有被正确定向”——尤其是跨函数传递、从 json/DB 加载、或用 new() 后忘记赋值时,容易漏掉这层检查。

text=ZqhQzanResources