Golang指针变量初始化有哪些方式_指针初始化方法对比

10次阅读

最常用且推荐的指针初始化方式是用 & 取已有变量地址;new(T) 用于分配零值内存但不适用于 slice/map/channel结构体指针优先用 &Struct{…} 而非 new()。

Golang指针变量初始化有哪些方式_指针初始化方法对比

用 & 取地址是最常用、最直观的初始化方式

当你已经有某个变量,想让指针指向它时,& 是唯一且最自然的选择。它要求操作对象必须是「可寻址的」——比如局部变量、结构体字段、切片元素(slice[i]),但不能是字面量(&42)、函数返回值(&fmt.Sprintf(...))或 map 元素(&m["key"],编译报错:cannot take address of map element)。

  • num := 42; ptr := &num ✅ 安全、清晰、推荐
  • ptr := &42 ❌ 编译失败
  • m := map[String]int{"a": 1}; ptr := &m["a"] ❌ 同样编译失败

这种初始化方式不分配新内存,只是记录已有变量的位置,开销极小,适合绝大多数场景。

用 new() 初始化零值内存,适用于无现成变量时

new(T) 会为类型 T 分配一块零值内存(如 int 得到 0string 得到 ""struct{} 所有字段均为零值),并返回 *T。它不支持 slicemapchannel ——对它们调用 new 虽然语法合法,但返回的是未初始化的空值(如 *[]int 指向一个 nil 切片),无法直接使用。

  • ptr := new(int)*ptr 初始为 0,可安全赋值:*ptr = 100
  • ptr := new([]int)*ptrnil 切片,len(*ptr) panic,必须后续 *ptr = make([]int, 5)
  • 结构体用 new(User) 不如 &User{Name: "Alice"} 灵活,后者能直接设字段值

结构体指针优先用 & + 字面量,而非 new()

初始化结构体指针时,&Struct{...} 是事实标准。它一步完成「构造值 + 取地址」,字段可按需赋初值;而 new(Struct) 只给零值,还得逐个赋值,代码更啰嗦、可读性差。

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

type Config struct {     Timeout int     Debug   bool }  // ✅ 推荐:简洁、意图明确、字段可定制 cfg := &Config{Timeout: 30, Debug: true}  // ⚠️ 不推荐:零值后手动赋值,冗余且易漏 c := new(Config) c.Timeout = 30 c.Debug = true

另外,go 对结构体指针做了隐式解引用优化:cfg.Timeout 等价于 (*cfg).Timeout,所以无需纠结语法糖,放心用 & 字面量。

别碰 make() + & 的组合,也别对 nil 指针解引用

make 返回的是值本身(如 map[string]int),不是指针;你不能写 &make(map[string]int),因为 make 返回的是不可寻址的临时值,编译直接报错。make 本就不该和 & 连用。

  • m := make(map[string]int); ptr := &m → 得到 *map[string]int,但几乎没用(map 本身已是引用类型
  • ptr := &make([]int, 5)编译错误:cannot take the address of make(…)
  • var p *int; *p = 1 ❌ 运行时 panic:invalid memory address or nil pointer dereference

真正容易被忽略的,是嵌套结构中字段指针未初始化就解引用——比如 user.Profile*Profile 类型,但没赋值,直接访问 user.Profile.Name 就会 panic。这类问题在 jsON 解析或 ORM 映射后尤其常见,务必检查非空。

text=ZqhQzanResources