new是Go中用于在堆上分配指定类型零值内存并返回其指针的内置函数,仅执行分配、置零、返回指针三步,不调用构造函数;适用于需零值指针且类型复杂、泛型或反射等场景。

new 是 Go 语言内置函数,用于在堆上分配指定类型的零值内存,并返回指向该内存的指针。它不调用构造函数(Go 没有构造函数),也不执行初始化逻辑,只做“分配 + 置零 + 返回指针”三件事。
new 的基本语法和行为
语法:new(T),其中 T 是任意类型(不能是接口、未定义类型或抽象类型如 func 或 map)。
返回值:类型为 *T 的指针,指向一个刚分配的、值为 T 类型零值的内存块。
- new(int) → 返回 *int,指向值为 0 的 int
- new(string) → 返回 *string,指向值为 "" 的 string
- new([]int) → 返回 *[]int,指向值为 nil 的切片
- new(struct{a int}) → 返回指向字段 a = 0 的 struct 实例的指针
new 和 & 取地址的区别
& 作用于一个已存在的变量,取其地址;new 是直接分配新内存并返回指针,无需先声明变量。
- p := &x:x 必须已定义(比如 x := 42),p 是 x 的地址
- p := new(int):一步到位,等价于先声明 var tmp int 再取地址 &tmp,但 tmp 不可访问
什么时候该用 new?
实际开发中,new 使用频率远低于 &T{} 或字面量取地址。它主要适合以下场景:
- 需要一个指向零值的指针,且类型名较长或嵌套较深,写 &T{} 显得冗余(例如 new(map[string][]byte))
- 泛型或反射场景中,类型 T 在编译期未知,只能靠 new(T) 动态分配
- 某些标准库内部实现(如 sync.Pool 的 New 字段回调)会约定使用 new 初始化零值
⚠️ 注意:new([]int) 得到的是 *[]int(指向 nil 切片),不是可直接 append 的切片指针;若需可操作的 slice,应写 &[]int{}[0:0] 或更推荐用 make([]int, 0) 配合取地址。
对比 make 和 new
make 仅用于 slice、map、chan 三种引用类型,返回的是值(不是指针),且完成初始化(如分配底层数组、哈希表结构等);new 适用于任意类型,返回指针,只做零值分配。
- new([]int) → *[]int,值为 nil
- make([]int, 5) → []int,长度 5,元素全为 0
- &[]int{1,2,3} → *[]int,指向含三个元素的 slice(更常用、更直观)
基本上就这些。new 是个简单但容易被高估的函数——多数时候,用字面量加 & 更清晰,只有明确需要“零值指针”且无初始化需求时才选它。








