在Golang的编程实践中,new和make是两个用于内存分配的内置函数,很多初学者甚至有一定经验的开发者,都容易混淆两者的使用场景和底层逻辑。理解这两个函数的差异,是写出规范Go代码的基础。
new函数的基本用法
new是Go语言的内置函数,它的作用是分配内存,返回指向该类型零值的指针。new函数适用于所有Go类型,包括基本类型、结构体、数组等。
new的函数签名如下:
func new(Type) *Type
下面通过一个简单示例展示new的使用:
package main
import "fmt"
type User struct {
Name string
Age int
}
func main() {
// 使用new分配int类型内存
intPtr := new(int)
fmt.Println(*intPtr) // 输出0,int的零值
// 使用new分配结构体类型内存
userPtr := new(User)
fmt.Println(userPtr.Name) // 输出空字符串,string的零值
fmt.Println(userPtr.Age) // 输出0,int的零值
}
make函数的基本用法
make同样是Go语言的内置函数,但它仅适用于切片、映射、通道这三种引用类型,作用是初始化这些类型并返回初始化后的实例,而不是指针。
make的函数签名根据类型不同有所区别:
func make(t Type, size ...IntegerType) Type
下面是make的使用示例:
package main
import "fmt"
func main() {
// 初始化切片,长度为2,容量为5
slice := make([]int, 2, 5)
fmt.Println(slice) // 输出[0 0]
// 初始化映射
m := make(map[string]int)
m["a"] = 1
fmt.Println(m) // 输出map[a:1]
// 初始化通道,缓冲区大小为2
ch := make(chan int, 2)
ch <- 1
fmt.Println(<-ch) // 输出1
}
new与make的核心差异
适用类型不同
new适用于所有Go类型,而make仅适用于切片、映射、通道这三种引用类型。如果尝试用make初始化其他类型,比如结构体或者基本类型,编译器会直接报错。
返回值不同
new返回的是指向类型零值的指针,也就是*Type类型;而make返回的是初始化后的类型实例本身,也就是Type类型,不需要通过指针间接访问。
内存分配逻辑不同
new仅分配内存,将分配的内存初始化为该类型的零值,不会做额外的初始化操作。而make除了分配内存之外,还会对切片、映射、通道进行初始化,比如切片的底层数组关联、映射的哈希表初始化、通道的环形队列初始化等,让这些类型可以直接使用。
使用场景对比
我们可以通过下面的表格更清晰地对比两者的使用场景:
| 对比维度 | new | make |
|---|---|---|
| 适用类型 | 所有Go类型 | 仅切片、映射、通道 |
| 返回值 | 指向零值的指针*Type | 初始化后的类型实例Type |
| 初始化操作 | 仅分配内存,初始化为零值 | 分配内存并做类型相关初始化 |
| 典型使用场景 | 需要获取类型指针的场景 | 初始化切片、映射、通道的场景 |
常见使用误区
很多开发者会误用这两个函数,比如尝试用new初始化切片:
package main
import "fmt"
func main() {
// 错误用法:new返回的是切片的指针,不能直接当切片使用
slicePtr := new([]int)
// 下面的代码会编译报错:slicePtr是*[]int类型,没有append方法
// *slicePtr = append(*slicePtr, 1)
fmt.Println(slicePtr)
}
上面的代码中,new([]int)返回的是*[]int类型,需要解引用之后才能操作,而且切片本身没有被初始化,底层数组是nil,直接append也会有问题。正确的初始化切片的方式是使用make。
另外,对于结构体类型,如果不需要指针,也可以直接声明变量,Go会自动分配内存并初始化为零值,不一定需要使用new:
package main
import "fmt"
type User struct {
Name string
Age int
}
func main() {
// 直接声明结构体变量,自动分配内存初始化为零值
var user User
fmt.Println(user.Name) // 输出空字符串
fmt.Println(user.Age) // 输出0
}
总结
new和make都是Go语言的内存分配函数,但适用场景完全不同。new适用于所有类型,返回指向零值的指针,仅做内存分配和零值初始化;make仅适用于切片、映射、通道,返回初始化后的实例,除了分配内存还会做类型相关的初始化。在实际开发中,需要根据要初始化的类型选择合适的函数,避免误用导致程序异常。
newmakeGolang内存分配Go语言修改时间:2026-06-27 07:42:34