Golang中new和make的区别
new 返回指针,任何类型
make 返回值,可用于 slice, map or channel
Go中的make和new的区别
·new:是一个用来分配内存的内置函数,与C++不同的是,它不初始化内存,只是将其归零,也就相当于,new(X)会为X的新项目分配被归零的存储,且返回它的地址,其中,第一个参数是类型,返回值是类型的指针,其值被初始化为‘0’,对于不同的数据类型,0值的意义也是不一样的,比如int初始化为0,bool初始化为false等等。
·make:是Golang的内置函数,仅用于分配和初始化slice、map及channel类型的对象,三种类型都是结构,返回值为类型而不是指针,例如slice是一个三元描述符,包含一个指向数据(在数组中)的指针,长度以及容量,在这些项被初始化前,slice都是nil的,对于这三者,make初始化这些内部数据结构,并准备好可用的值。
需要注意的是,make只用于map、slice和channel,并且不反悔指针,想要获得一个显式的指针,使用new进行分配,或者显式地使用一个变量的地址。
new和make的区别?
它们都是内置函数,new按指定类型长度分配零值内存,返回指针,并不关系类型内部构造和初始化方式。而引用类型则必须使用make函数创建,编译器会将make转化为目标类型专用的创建函数(或指令),以保证完成全部内存分配和相关属性初始化。
new可以为引用类型分配内存,但这是不完整创建。以字典(map)为例,它仅分配了字典类型本身(实际就是个指针包装)所需内存,并没有分配键值存储内存,也没有初始化散列桶等内部属性,因此它无法正常工作。
p := new(map[string]int) // 函数new返回指针
m := *p
m["a"] = 1 // panic: assignment to entry in nil map (运行期错误
使用make初始化引用类型
切片的存储形式 unsafe.pointer len cap
只声明不赋值时
使用make初始化时 会分配底层数组
使用new初始化引用类型
使用new初始化引用类型 (new的返回值就是slice结构的起始地址,不会分配底层数组,所以此时赋值时不允许的)
使用append的方式添加元素,可以分配底层数组
参考: 【Golang】slice类型存什么?make和new?slice和数组?扩容规则?_哔哩哔哩_bilibili
new和make
new是一个内置的函数,它的函数签名如下:
funcnew(Type)*Type
其中,
Type表示类型,new函数只接受一个参数,这个参数是一个类型
*Type表示类型指针,new函数返回一个指向该类型内存地址的指针。
new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。
make也是用于内存分配的,区别于new,它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。make函数的函数签名如下:
funcmake(t Type,size...IntegerType)Type
make函数是无可替代的,我们在使用slice、map以及channel的时候,都需要使用make进行初始化,然后才可以对它们进行操作。这个我们在上一章中都有说明,关于channel我们会在后续的章节详细说明。
相同点:
二者都是用来做内存分配的。
不同点:
make 只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
new 用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。