在 Go 语言中,new
和 make
都是用于分配内存的内建函数,但它们适用于不同的类型,并且它们的行为也有所不同。理解这两者的区别对于正确地初始化数据结构至关重要。
new(T)
- 用途 :
new(T)
为类型T
分配零值并返回指向它的指针(即*T
)。 - 初始化 :分配的内存被初始化为该类型的零值。例如,对于数字类型,零值是
0
;对于布尔类型,零值是false
;对于字符串,零值是空字符串""
;对于指针,零值是nil
。 - 适用类型:可以用于任何类型,包括自定义类型、结构体等。
- 返回值 :返回一个指向类型
T
的指针。
示例:
go
type MyStruct struct {
value int
}
p := new(MyStruct)
// p 是 *MyStruct 类型的指针,其成员变量 value 被设置为其零值 0
make(T, args...)
- 用途 :
make
只能用于切片(slice)、映射(map)和通道(channel),它会分配内存并且返回类型的初始化值而非指针。 - 初始化 :与
new
不同,make
返回的是类型的初始值而不是指针,并且会对这些类型进行必要的初始化操作。例如,创建一个切片时,make
会分配底层数组并返回一个包含引用的切片。 - 适用类型:仅限于 slice、map 和 channel。
- 返回值:直接返回类型 T 的实例,不是指针。
示例:
go
s := make([]int, 5) // 创建了一个长度为5的int类型的切片,所有元素都被初始化为0
m := make(map[string]int) // 创建了一个string到int的映射
ch := make(chan int) // 创建了一个无缓冲的整数通道
总结
- 使用
new(T)
分配类型T
的零值,并返回指向它的指针。 - 使用
make(T, args...)
初始化并返回 slice、map 或者 channel 类型的值本身,而不仅仅是零值或 nil。
因此,在选择使用 new
还是 make
时,请根据你正在处理的数据类型来决定。如果你需要初始化 slice、map 或 channel,那么你应该使用 make
。而对于其他类型的初始化,尤其是当你需要一个指向某类型的指针时,应该使用 new
。