搞懂golang make和new的区别

make和new都是用来分配内存的。相比make,new的使用场景很少。面试经常被问,来看看这两个具体什么区别

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接收一个参数,可以是任意类型,返回的是该类型的指针。输出看下

func main() {
    
    
	a := new([]int)
	fmt.Printf("%T  %p\n", a, a)
}

结果:

*[]int 0xc000004480

a的类型是我们传入的 []int 类型的指针 *[]int
0xc000004480是该指针的地址
不会进行初始化,new完的map不能直接使用,会panic
new会将类型置为零值

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

看函数的原型,第一个参数是类型,看注释,类型仅支持 map、slice、channel。
第二个参数是大小。

func main() {
    
    
	//a := new([]int)
	//fmt.Printf("%T  %p\n", a, a)
	var a map[int]int
	a = make(map[int]int, 8)
	var b []int
	b = make([]int, 8)
	fmt.Println(len(b), cap(b), b)
	fmt.Printf("%T  %v  %v\n", a, a, len(a))
	c := make(chan int,5)
	fmt.Println(c, len(c))
}

结果

map[int]int map[] 0
8 8 [0 0 0 0 0 0 0 0]
0xc000076000 0

初始化完成后,类型是传入类型对应的一个实例
对于第二个参数 size,对于slice,传入的参数初始化完成后参数对应的是切片的 len和cap 均为size,并且切片中得值初始化为零值
对于map,size为 map 的大小
对于channel,不指定size的,表示该channel为无缓冲的channel,指定了大小的,表示该channel 为有缓冲的channel

总结

make仅仅能用于初始化 map、slice、channel。而且对于map和channel,必须初始化之后才能使用否则会报错

map未初始化

panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()

channel 未初始化

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive (nil chan)]:
main.main()

new 仅仅是为对应类型申请一片内存空间,然后返回该内存对应的指针

猜你喜欢

转载自blog.csdn.net/weixin_43753680/article/details/114302192