golang 中有两个内建函数new, make,用于内存分配与初始化。在面试中这两种内建函数有何不同之处会经常被问到,因此笔者进行下列总结。
1. new(T)
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.”
new在处理三种复合类型会出现问题:channel、slice、map. 这三种类型比较特殊,它们的底层类型指向一片需要初始化的内存状态。例如:slice 的底层类型中含有一个指针字段指向一个内部的数组的首元素、一个length字段标识数组中可以被访问的元素数量、一个cap字段标识数组的容量。 而new方法不能分配slice存储元素需要的底层数组,map与channel情况类似。
Note:ptr的值为nil,此时访问slice会panic.
2. make(T, args)
make 用于解决new面对slice、map、channel时的问题,它不仅会分配类型本身需要的内存,也会初始化类型底层状态需要的内存;例如对于slice会为ptr分配一片内存区域用于存储slice的数据;同时make的返回值为T而非*T.
3. 总结
- new 返回一个指向T类型的指针,而make返回T类型
- new 不能为slice、map、channel分配底层状态需要的存储内存,make可以解决这个问题。