Golang 基本语法 —— var、new、make区别及使用
make和new是内置函数,不是关键字,var是关键字。 make 只能用来分配及初始化类型为 slice、map、chan 的数据,而 new 可以分配任意类型的数据。 new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type。 new 分配的空间被清零。make 分配空间后,会进行初始化。
一:对于值类型的变量,我们通过var 声明(包括结构体),系统会默认为他分配内存空间,并赋该类型的零值。如下,我们声明一个int类型变量i,输出为0。
|
|
而如果我们声明一个指针类型的变量,系统不会为他分配内存(应该是不会为这个指针分配一个内存给他指向),默认就是nil。此时如果你想直接使用,那么系统会抛异常。
|
|
空指针还没指向任何内存,是不能使用的。
二:那么要想使用,此时就需要new出场啦。
|
|
声明指针类型变量后,通过new为他分配指向的内存,有了内存空间,这个变量就可以自由的使用了。
来看一下new函数的签名:
它只接受一个参数,这个参数是一个类型,**分配好内存后,返回一个指向该类型内存地址的指针。这块内存上存的是类型的零值。**这个类型也能是指针。
|
|
- *但是,**实际在工程使用中,通常是直接声明指针使用,不需要new操作。
三:make和new不同,make用于map, slice,chan 的内存创建,因为他们三个是引用类型,直接返回这三个类型本身。make签名是:
|
|
make 是分配内存并初始化,初始化并不是置为零值。
与new一样,它的第一个参数也是一个类型,但是不一样的是,make返回的是传入的类型,而不是指针!
|
|
总结:
var 分配内存,赋0值,返回类型
new 分配内存,赋0值,返回类型指针(指向刚才分配内存的指针)
make给map,channel,slice分配内存,不赋0值,返回类型
Var指针类型一般是var+new;Var三种引用类型时候,一般是var+make
make和new的区别
- new 和 make都是用来创建和分配内存的,可能在栈上,也可能在堆上,是内存逃逸分析后确定创建在哪里的。
new
返回的是指针,指向新分配的类型的零值;make
返回的是值,这个值已经被初始化(例如,一个新的切片,它的元素已经被分配了内存)。new
可以用于任何类型,而make
只能用于切片、映射和通道。make
创建的切片、映射或通道已经准备好使用,而new
创建的值需要进一步初始化。
为什么要给三种引用类型单独实现一个make 函数?
这是因为slice, map和chan的底层结构上要求在使用slice,map和chan的时候必须初始化,如果不初始化,那slice,map和chan的值就是零值,也就是nil。我们知道:
- map如果是nil,是不能往map插入元素的,插入元素会引发panic
- chan如果是nil,往chan发送数据或者从chan接收数据都会阻塞
- slice会有点特殊,理论上slice如果是nil,也是没法用的。但是append函数处理了nil slice的情况,可以调用append函数对nil slice做扩容。但是我们使用slice,总是会希望可以自定义长度或者容量,这个时候就需要用到make。
那么,可以使用new来初始化引用类型吗?可以的!
参考
https://huweicai.com/ https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-make-and-new/ https://blog.wu-boy.com/2021/06/what-is-different-between-new-and-make-in-golang/ https://fivezh.github.io/2020/03/15/golang-new-make/ https://zhuanlan.zhihu.com/p/486998884 http://www.codingbygolang.com/make-or-new/#%E5%87%BD%E6%95%B0-new-%E7%AD%BE%E5%90%8D