Golang 中 make 与 new 的区别

make

make 内建函数,只能用来作为 slicemapchannel 的声明,返回的是类型本身,而不是指针,因为它们本身就是一个引用类型。并且会对其进行一些初始化操作。例如,slice 在创建时,会初始化底层数组,并且初始化 slice 的长度、指针和容量等基础数据。

1
s := make([]int, 0, 5) // 创建 slice
2
m := make(map[string]int) // 创建 map
3
c := make(chan int) // 创建 channel

new

newmake 不同,使用 new 声明的类型,会同时分配一块内存,分配内存后,会返回指向该类型内存地址的指针,并且将会被分配为该类型的零值。下面这个例子可以看到这一做法的好处:

1
type People struct {
2
    Name string
3
    Age int8
4
}
5
6
type User struct {
7
    People
8
    Psw string
9
}
10
11
func f () {
12
    var u = new(User)
13
    fmt.Println(fmt.Sprintf("%s", u.Name))
14
}

这里,如果没有这个机制,以上代码在调用输出 u.Name 这里将会产生一个 nilPoint 的 panic。但是,因为在 new 的时候,默认已经初始化了 User 以及 User 中所有字段为零值。所以,调用时就不会出现 panic

两者对比

首先,两者都是用作变量声明时的内存分配,两者的内存分配空间都为堆。但是 make 只能声明 slicemapchannel,而 new 用于类型的内存分配,并且初始化所有内容为零值。
其次,make 返回类型本身,而 new 返回的是类型的引用指针。
再则,new 不常用,一般使用 := 代替。而 make 函数无法替代,因为 slicemapchannel都需要它来声明。