new 和 make 都可以用来分配空间,初始化类型

new和make的区别

new 用来分配内存,作用值类型和用户定义的类型,并初始化零值,返回零值指针

make 用来分配内存,作用内置引用类型(map, slice, channel),并初始化零值,返回返回引用类型本身

源码返回区别

make(T) 返回的初始化的 T,只能用于 slice,map,channel

1
2
// $GOROOT/1.11.5/libexec/src/builtin/builtin.go
func make(t Type, size ...IntegerType) Type

new(T) 返回 T 的指针 *T 并指向 T 的零值

1
func new(Type) *Type

Local Picture

示例

new(T) 为一个 T 类型新值分配空间并将此空间初始化为 T 的零值,返回的是新值的地址,也就是 T 类型的指针 *T,该指针指向 T 的新分配的零值。

1
2
3
4
5
6
7
8
p1 := new(int)
fmt.Printf("p1 --> %#v \n ", p1)           //(*int)(0xc0000160d8)
fmt.Printf("p1 point to --> %#v \n ", *p1) //0
var p2 *int
i := 0
p2 = &i
fmt.Printf("p2 --> %#v \n ", p2)           //(*int)(0xc0000160e0)
fmt.Printf("p2 point to --> %#v \n ", *p2) //0

make 只能用于 slice,map,channel 三种类型,make(T, args) 返回的是初始化之后的 T 类型的值,这个新值并不是 T 类型的零值,也不是指针 *T,是经过初始化之后的 T 的引用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var s1 []int
if s1 == nil {
    fmt.Printf("s1 is nil --> %#v \n ", s1) // []int(nil)
}
s2 := make([]int, 3)
if s2 == nil {
    fmt.Printf("s2 is nil --> %#v \n ", s2)
} else {
    fmt.Printf("s2 is not nil --> %#v \n ", s2) // []int{0, 0, 0}
}

参考