new()和make()是go语言中的内置函数,先来看下两个函数的说明

new

// 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

new 会分配内存,第一个参数是变量类型。new 会创建一个未命名的Type类型的变量,初始化为Type类型的零值,并返回其地址(*Type)

make

// 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

make 方法也会分配内存,并初始化slice,map,chan类型的对象。和new一样第一个参数是变量类型,不过make方法返回值是一个Type类型的变量,不是指针。对于不同的参数类型,返回的结果不一样:

  • slice: size参数指定了silce的长度,并且默认容量和长度一致,如过想指定silce的容量,需要指定第二个int参数(不能比size参数小,否则会报错),例如:make([]int, 0, 10) 将会分配一个底层长度为10的int数组,返回一个长度为0容量为10的silce
  • map: 分配一个能够容纳指定数量元素的空map,如果size被忽略,将分配最小的内存
  • channel: 初始化一个缓冲区大小为size的channel,如果忽略size,初始化一个无缓冲的channel

由此可见,make函数只是用来为silce,map,channel类型申请分配内存,而new可以为普通的数据类型申请内存。如果用new来给map申请空间是否可行呢

a := new(map[string]int)
fmt.Println(a)
// 输出
// &map[]

看起来也可以

a := new(map[string]int)
(*a)["age"]=12
fmt.Println(a)
// 结果
// panic: assignment to entry in nil map

使用的时候panic了

这时我们再看new()函数说明,new会分配内存,并初始化为零值,map的零值是nil,不能再nil上赋值,所以需要显式的赋值一次

a := new(map[string]int)
a = &map[string]int{}
(*a)["age"]=12
fmt.Println(a)
// 结果
//&map[age:12]

虽然可以用了,但感觉繁琐了