在Go中,make和new都可以用来初始化变量。那这两个内置函数在使用上的区别是什么呢?
定义
先来看看这两个内置函数的定义:
// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
// Slice: The size specifies the length. The capacity of the slice is
// equal to its length. A second integer argument may be provided to
// specify a different capacity; it must be no smaller than the
// length. For example, make([]int, 0, 10) allocates an underlying array
// of size 10 and returns a slice of length 0 and capacity 10 that is
// backed by this underlying array.
// Map: An empty map is allocated with enough space to hold the
// specified number of elements. The size may be omitted, in which case
// a small starting size is allocated.
// Channel: The channel's buffer is initialized with the specified
// buffer capacity. If zero, or the size is omitted, the channel is
// unbuffered.
func make(t Type, size ...IntegerType) Type
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
go1.17.10 src/builtin/builtin.go
相同点
- 都可以用来初始化变量
- 参数都是某个类型,而不是一个具体的值
不同点
从这两个内置函数的定义,我们能直观看出:
-
参数不同
- make可以传递多个参数,第一个是类型,第二个开始为int类型的数字
- new只有一个参数,参数是类型
-
返回值不同
- make初始化变量返回值类型
- new初始化变量返回零值的指针类型
-
适用类型不同
- make只用于map、slice和chan类型的初始化
make用于slice、map和chan类型
make用于初始化slice
// 初始化一个长度为0的slice
slice1 := make([]int, 0)
// 初始化一个长度为0,容量为10的slice
slice2 := make([]int, 0, 10) // 分配一个大小为10的底层数组并返回一个长度为0,容量为10的slice
make用于初始化slice的时候,有三个可用参数:
- 第一个:slice的类型,必填参数
- 第二个:slice的长度,必填参数
- 第三个:slice的容量,不能比slice的长度小,非必填参数
make用于初始化map
m1 := make(map[string]string)
m2 := make(map[string]string, 10)
make用于初始化map的时候,有两个可用参数:
- 第一个:map的类型,必填参数
- 第二个:map的起始空间大小,非必填
当map的大小不指定的时候,会默认分配一个较小的起始空间。
make用于初始化chan
// 初始化一个不带缓冲的int类型的channel
c1 := make(chan int)
// 初始化一个带缓冲且大小为10的int类型的channel
c2 := make(chan int, 10)
make用于初始化channel的时候,有两个可用参数:
- 第一个:chan的类型,必填参数
- 第二个:chan的缓冲大小,非必填