Go语言new()和make()函数的区别(附带实例)
在 Go 语言中,内置函数 new() 和 make() 都用于内存分配。
new() 只分配内存,而 make() 为切片、集合以及通道的数据类型分配内存和初始化。
根据语法定义分别创建整型、字符串、集合、切片和通道的变量,示例代码如下:
结合运行结果与内置函数 new() 的特性,我们能得出以下结论:
1) 内置函数 new() 适用于所有数据类型。
2)使用 new() 创建变量,其变量值以指针方式表示,并且指针存储的数据为零,如整型为 0,字符串为空字符串,布尔为 false,切片为空切片,集合为空集合等。
new() 创建的变量以指针表示,那么它与指针之间又存在怎样的关系呢?我们通过下面的例子加以说明:
从运行结果看到,内置函数 new() 与指针的差异说明如下:
1) 内置函数 new() 创建的变量是指针变量,并且已分配了对应的内存地址,可以直接对变量执行赋值操作。以直接对变量执行赋值操作。
2) 使用 var 定义指针变量,它的数据和内存地址皆为空值(nil),操作指针变量必须设置具体的内存地址,因此还需要绑定某个变量的内存地址。
3) 内置函数 new() 等于实现了指针的定义与赋值过程,指针赋值是指针变量设置具体的内存地址,并不是在内存地址中存放数值。
在 GoLand 中查看 make() 源码信息,源码及注释说明如下:
根据 make() 语法定义分别创建切片、集合以及通道的变量,示例代码如下:
1) 内置函数 make() 能直接创建切片、集合以及通道的变量。
2) 变量的值为零,如切片为空切片,每个切片元素为0或空字符串;集合为空集合,没有任何成员;通道为空通道,不寄存任何数据。
综上所述,内置函数 new() 和 make() 的区别如下:
1) new() 适用于所有数据类型,make() 仅适用于切片、集合以及通道的数据类型。
2) new() 创建的变量以指针形式表示,make() 创建的变量是某个数据类型的变量。
3) new() 仅有参数 Type,代表变量的数据类型;make() 的参数 Type 代表变量的数据类型,参数 size...IntegerType 是可选参数,用于设置切片、集合、通道的长度或容量。
new() 只分配内存,而 make() 为切片、集合以及通道的数据类型分配内存和初始化。
Go new()函数
首先分析内置函数 new(),在 GoLand 中查看 new() 源码信息,源码说明如下:func new(Type) *Typenew() 语法说明如下:
- 函数参数 Type 用于创建变量的数据类型。
- 返回值 *Type 以指针形式表示,说明创建的变量以指针表示。
根据语法定义分别创建整型、字符串、集合、切片和通道的变量,示例代码如下:
package main import "fmt" func main() { // 为变量myInt创建Int类型的内存地址 myInt := new(int) fmt.Printf("myInt类型:%T,数值:%v,地址:%v\n", *myInt,*myInt,myInt) // 为变量myStr创建String类型的内存地址 myStr := new(string) fmt.Printf("myStr类型:%T,数值:%v,地址:%v\n", *myStr,*myStr,myStr) // 为变量myMap创建Map类型的内存地址 myMap := new(map[string]string) fmt.Printf("myMap类型:%T,数值:%v,地址:%v\n", *myMap,*myMap,myMap) // 为变量mySli创建Slice类型的内存地址 mySli := new([]int) fmt.Printf("mySli类型:%T,数值:%v,地址:%v\n", *mySli,*mySli,mySli) // 为变量myChan创建Channel类型的内存地址 myChan := new(chan string) fmt.Printf("myChan类型:%T,数值:%v,地址:%v\n", *myChan,*myChan,myChan) }运行上述代码,运行结果为:
myInt类型:int,数值:0,地址:0xc0000ac058
myStr类型:string,数值:,地址:0xc000088230
myMap类型:map[string]string,数值:map[],地址:&map[]
mySli类型:[]int,数值:[],地址:&[]
myChan类型:chan string,数值:<nil>,地址:0xc0000d8028
结合运行结果与内置函数 new() 的特性,我们能得出以下结论:
1) 内置函数 new() 适用于所有数据类型。
2)使用 new() 创建变量,其变量值以指针方式表示,并且指针存储的数据为零,如整型为 0,字符串为空字符串,布尔为 false,切片为空切片,集合为空集合等。
new() 创建的变量以指针表示,那么它与指针之间又存在怎样的关系呢?我们通过下面的例子加以说明:
package main import "fmt" func main() { // 为变量myInt创建Int类型的内存地址 myInt := new(int) // 给变量myInt赋值 *myInt = 666 fmt.Printf("myInt类型:%T,数值:%v,地址:%v\n", *myInt,*myInt,myInt) // 定义指针变量myPro var myPro *int // 输出指针变量的信息 fmt.Printf("myPro类型:%T,数值:%v,地址:%v\n", myPro,myPro,myPro) // 定义变量num并赋值 num := 777 // 将变量num的内存地址赋予指针myPro myPro = &num // 输出指针变量的信息 fmt.Printf("myPro类型:%T,数值:%v,地址:%v\n", *myPro,*myPro,myPro) }运行上述代码,运行结果为:
myInt类型:int,数值:666,地址:0xc0000180a8
myPro类型:*int,数值:<nil>,地址:<nil>
myPro类型:int,数值:777,地址:0xc0000180f0
从运行结果看到,内置函数 new() 与指针的差异说明如下:
1) 内置函数 new() 创建的变量是指针变量,并且已分配了对应的内存地址,可以直接对变量执行赋值操作。以直接对变量执行赋值操作。
2) 使用 var 定义指针变量,它的数据和内存地址皆为空值(nil),操作指针变量必须设置具体的内存地址,因此还需要绑定某个变量的内存地址。
3) 内置函数 new() 等于实现了指针的定义与赋值过程,指针赋值是指针变量设置具体的内存地址,并不是在内存地址中存放数值。
Go make()函数
内置函数 make() 仅用于分配和初始化切片、集合以及通道的数据类型。在 GoLand 中查看 make() 源码信息,源码及注释说明如下:
func make(t Type, size ...IntegerType) Typemake() 语法说明如下:
- 函数参数 t 是创建的变量的数据类型,仅允许设置切片、集合以及通道的数据类型;
- 函数参数 size...IntegerType 是可选参数,用于设置切片、集合、通道的长度或容量;
- 返回值 Type 是已创建的变量。
根据 make() 语法定义分别创建切片、集合以及通道的变量,示例代码如下:
package main import "fmt" func main() { // 创建切片类型的变量mySli,切片长度和容量为10 mySli := make([]int, 10) // 对切片第一个元素赋值 mySli[0] = 666 // 输出切片信息 fmt.Printf("mySli数值:%v,长度:%v,容量:%v\n",mySli,len(mySli),cap(mySli)) // 创建集合类型的变量myMap myMap := make(map[string]string) // 设置集合的成员值 myMap["name"] = "Tom" // 输出集合信息 fmt.Printf("myMap数值:%v,成员数量:%v\n", myMap, len(myMap)) // 创建通道类型的变量myChan,容量为10 myCh := make(chan string, 10) // 往通道写入数据 myCh <- "hello" // 输出通道信息 fmt.Printf("myCh数值:%v,已用缓存:%v,容量:%v\n",myCh,len(myCh),cap(myCh)) }运行上述代码,运行结果为:
mySli数值:[666 0 0 0 0 0 0 0 0 0],长度:10,容量:10
myMap数值:map[name:Tom],成员数量:1
myCh数值:0xc0000e4060,已用缓存:1,容量:10
1) 内置函数 make() 能直接创建切片、集合以及通道的变量。
2) 变量的值为零,如切片为空切片,每个切片元素为0或空字符串;集合为空集合,没有任何成员;通道为空通道,不寄存任何数据。
综上所述,内置函数 new() 和 make() 的区别如下:
1) new() 适用于所有数据类型,make() 仅适用于切片、集合以及通道的数据类型。
2) new() 创建的变量以指针形式表示,make() 创建的变量是某个数据类型的变量。
3) new() 仅有参数 Type,代表变量的数据类型;make() 的参数 Type 代表变量的数据类型,参数 size...IntegerType 是可选参数,用于设置切片、集合、通道的长度或容量。