24.2 new 和 make 的区别

new() 和 make() 都在堆上分配内存,但是它们的行为不同,适用于不同的类型。

new() 用于值类型的内存分配,并且置为零值。 make() 只用于切片、字典以及通道这三种引用数据类型的内存分配和初始化。

new(T) 分配类型 T 的零值并返回其地址,也就是指向类型 T 的指针。 make(T) 返回类型T的值(不是* T)。

然而在Go语言中,并不能准确判断变量是分配到栈还是堆上。在C++中,使用 new() 创建的变量总是在堆上。在Go中变量的位置是由编译器决定的。编译器根据变量的大小和泄露(逃逸)分析的结果来决定其位置。

如果想确切知道变量分配的位置,可在执行go build或go run时加上-m gc标志(即go run -gcflags -m app.go)。例如:

go run -gcflags -m main.go
# command-line-arguments
.\main.go:12:31: m.Alloc / 1024 escapes to heap
.\main.go:11:23: main &m does not escape
.\main.go:12:12: main ... argument does not escape