new()仅分配零值内存并返回指针,非构造函数;日常应优先用& t{}或make,new极少使用。

new() 函数只做一件事:分配零值内存并返回指针
new 不是构造函数,也不调用任何初始化逻辑,它只是申请一块对应类型的零值内存,并返回指向它的指针。比如 new(int) 返回一个 *int,其指向的值一定是 0;new(string) 返回 *string,其指向的值是空字符串 ""。
它和 &T{} 或 &struct{} 的区别在于:前者只能得到零值,后者在结构体场景下可带字段初始化(但注意——&T{} 本质是复合字面量取地址,不是 new)。
什么时候该用 new(),什么时候不该用
绝大多数情况下你**不需要**显式调用 new。Go 推荐直接写 p := &T{} 或更简洁地让编译器推导:p := new(T) 和 p := &T{} 对于零值初始化效果相同,但后者更常见、更易读。
-
new无法初始化非零值字段(比如你想让*int指向42,必须写p := new(int); *p = 42,不如p := new(int); *p = 42直观,但远不如p := &42或i := 42; p := &i) - 对结构体,
new(MyStruct)得到的是所有字段为零值的实例,而&MyStruct{Field: "ok"}可以指定部分字段,更灵活 - 切片、map、channel 等引用类型本身已是“类似指针”的描述符,
new([]int)返回的是*[]int(即指向切片头的指针),极少需要——你要的是切片本身,不是“指向切片的指针”
new() 常见误用与错误现象
新手容易把 new 当作“创建对象”的通用方式,结果写出难以维护或语义不清的代码。典型问题包括:
- 写
new([]*int)以为得到了一个可 append 的指针切片,实际得到的是一个指向 nil 切片的指针,后续解引用再操作会 panic - 对 map 使用
new(map[string]int,得到*map[string]int,但该指针所指仍是 nil map,直接*m["k"] = 1会 panic:assignment to entry in nil map - 混淆
new(T)和make(T, ...):后者专用于 slice/map/channel 的内存分配与初始化,new对这三者只分配头结构(零值),不准备底层数据结构
替代方案:make 和复合字面量更实用
真正需要初始化引用类型时,优先选 make;需要零值结构体指针时,优先写 &T{}。
例如:
// ✅ 推荐:语义清晰,且支持字段初始化
p1 := &bytes.Buffer{}
p2 := &MyStruct{Name: "foo"}
// ✅ 切片:make 分配底层数组
s := make([]int, 0, 10)
// ✅ map:make 初始化哈希表
m := make(map[string]int)
// ❌ 不推荐:new([]int) 返回 *[]int,几乎无实用场景
ptrToSlice := new([]int)
只有极少数底层场景(比如实现某些泛型工具函数需统一处理任意类型指针)才可能用到 new,日常业务代码里它基本是“被遗忘的函数”。
记住:Go 里声明指针变量最自然的方式是 p := &v 或 p := &T{},而不是 p := new(T) —— 后者存在,但容易让人多想一层“我是不是漏了什么初始化”。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











