go语言(golang)中,make和new有什么区别呢?

高手哪位知道,go语言(golang)中,make和new有什么区别呢?
最新回答
肆无忌惮的思念

2025-02-25 01:08:53

在Go语言中,初始化数据结构的时候,可能会用到2个内置函数:new和make。那么new和make有什么区别呢?在写代码过程中,对于new和make的最佳实践又是什么呢?

new函数在Go语言中用于分配内存,其官方定义为:func new(Type) *Type。从定义中可以看到,new函数的参数是一个类型,而不是一个值,并且返回的是一个指向该类型零值的指针。

注意:Go里的new和C++的new是不一样的。C++的new函数分配内存并初始化对象,而Go语言中的new函数只用于分配内存。

make函数同样用于分配内存,但是它的功能更加强大。make函数的官方定义为:func make(t Type, size ...IntegerType) Type。这个函数可以用于创建slice、map、channel类型的数据结构。

如果是用于slice类型,make函数的第二个参数表示slice的长度,这个参数必须给值。对于map类型,make函数会创建一个空map。对于channel类型,make函数会初始化channel的缓冲区。

在使用new和make函数的过程中,我们经常会遇到以下一些问题:

问题:为什么使用make函数创建slice、map、channel后,它们的值是nil?

答案:这是因为slice、map和channel的底层结构上要求在使用时必须初始化。如果不初始化,那slice、map和channel的值就是零值,也就是nil。我们知道,nil在Go语言中表示空指针,即未分配内存。

问题:new函数可以用来创建slice、map、channel吗?

答案:理论上new函数可以用来创建slice、map、channel,但是实际上并没有卵用,因为new创建的slice、map、channel的值都是零值,也就是nil。这3种类型如果是nil,那遇到的问题我们在上面第一个问题已经解答过了,这里不再赘述。

问题:对于nil slice,append函数是如何工作的?

答案:对于nil slice,append函数会对slice的底层数组做扩容,通过调用mallocgc向Go的内存管理器申请内存空间,再赋值给原来的nil slice。

在编写代码时,new和make的选择应根据具体需求来决定。new函数适用于需要创建指针类型的零值场景,而make函数适用于创建特定类型的零值数据结构。

对于new和make的最佳实践,建议在使用new函数时,直接为指针类型分配内存,避免不必要的复杂性。对于make函数,应确保在创建数据结构时提供足够的初始化参数,避免使用零值。

为了便于参考和学习,相关代码和文章已开源至GitHub:github.com/jincheng9/go...

欢迎关注公众号:coding进阶,学习更多Go知识。

参考资料