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

用 & 取地址是最常用、最直观的初始化方式
当你已经有某个变量,想让指针指向它时,& 是唯一且最自然的选择。它要求操作对象必须是「可寻址的」——比如局部变量、结构体字段、切片元素(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 得到 0,string 得到 "",struct{} 所有字段均为零值),并返回 *T。它不支持 slice、map、channel ——对它们调用 new 虽然语法合法,但返回的是未初始化的空值(如 *[]int 指向一个 nil 切片),无法直接使用。
-
ptr := new(int)→*ptr初始为0,可安全赋值:*ptr = 100 -
ptr := new([]int)→*ptr是nil切片,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 映射后尤其常见,务必检查非空。










