new 函数
new 是 Go 内置函数,签名:
go
func new(Type) *Type
new函数的作用是:
为指定类型分配一块内存,随后将内存清零(置为零值),最后返回指向该类型的指针
也就意味着,new函数不会做任何初始化工作
new可以作用于所有类型:int、string、struct、数组、切片、map、channel 都能用 new。
但是 slice/map/chan 用 new 几乎没用,因为它们必须初始化才能使用。
简单代码示例:
go
package main
import "fmt"
func main() {
// 1. 给 int 分配内存,返回 *int
num := new(int)
fmt.Println(*num) // 0(自动清零)
*num = 100
fmt.Println(*num) // 100
// 2. 给结构体分配内存
type User struct {
Name string
Age int
}
u := new(User)
fmt.Println(u) // &{ "" 0 }
u.Name = "张三"
}
make函数
make 签名:
go
func make([]T, len ...cap) []T
func make(map[K]V) map[K]V
func make(chan T) chan T
make()只用于 slice、map、channel 三种引用类型:
- 分配内存 + 完成初始化
- 返回类型本身(不是指针)
- 可以直接使用(赋值、存取、发送接收)
代码示例:
go
package main
import "fmt"
func main() {
// 1. 切片:初始化 len=5, cap=10
s := make([]int, 5, 10)
s[0] = 10
// 2. map:初始化,可以直接存值
m := make(map[int]string)
m[1] = "go"
// 3. channel:初始化
ch := make(chan int, 2)
ch <- 100
}
关键特点为
- 必须用于三种引用类型
- 返回类型本身,不是指针
- 分配 + 初始化,创建后可直接使用
- 支持传入长度、容量参数
make() 与 new() 的区别
看起来二者没有什么区别,都在堆上分配内存,但是它们的行为不同,适用于不同的类型。
new(T)为每个新的类型T分配一片内存,初始化为0并且返回类型为*T的内存地址:这种方法 返回一个指向类型为T,值为0的地址的指针 ,它适用于值类型如数组和结构体;它相当于&T{}。make(T)返回一个类型为 T 的初始值 ,它只适用于 3 种内建的引用类型:切片、map和channel
换言之,new() 函数分配内存,make() 函数初始化;下图给出了区别:

如何理解 new、make、slice、map、channel 的关系
1.slice、map 以及 channel 都是 golang 内建的一种引用类型,三者在内存中存在多个组成部分, 需要对内存组成部分初始化后才能使用,而 make 就是对三者进行初始化的一种操作方式
2. new 获取的是存储指定变量内存地址的一个变量,对于变量内部结构并不会执行相应的初始化操作, 所以 slice、map、channel 需要 make 进行初始化并获取对应的内存地址,而非 new 简单的获取内存地址