我们可以通过 var+变量名称+变量类型 进行声明变量,当我们没有给它赋值的时候,它们的结果是变量类型的零值。
比如说 string 的零值是"", int 的零值是0,引用类型的零值是nil。
以上两种类型我们可以直接使用,但如果把它改成指针会怎么样呢?
执行结果如下:这是为什么呢,因为对于引用类型的变量,不仅要声明,并且还要给它分配内存。怎么给它分配内存呢?这就要用到了new了
什么是newnew 是 Golang 的内置函数,源代码如下:
大意是,分配内存的内置函数,第一个参数是类型,而不是具体的值,返回值是该类型的指针。分配的值是该类型零值的指针。
“我知道怎么改了” 学妹兴奋的说道,说完便在编辑器加了两行代码。
复合类型的slice、map、chan使用 new 后可以使用吗?为什么呢
执行下代码,竟然报错了,“这是为什么呢?”
map 底层是结构体
Talk is cheap. Show me the code
也就是说它里面的成员变量仍未进行初始化,所以它们几个初始化要使用make来进行。
make 也是用于内存分配的内置函数,但是和new不同,源码如下图所示。
大意是make内置函数分配并初始化一个slice、map或chan类型的对象。像new函数一样,第一个参数是类型,而不是值。
与new不同,make的返回类型与其参数的类型相同,而不是指向它的指针。结果的取决于传入的类型。
并且 slice在 make 的时候,第二个参数必须传递,也就是切片的长度。否则会编译失败。
new函数底层实现
new函数底层主要是调用go1.17/src/runtime/malloc.go中的 newobject 方法。
编辑切换为居中
添加图片注释,不超过 140 字(可选)
这里可以看到 newobject 方法,底层调用 mallocgc 方法的时候,needzero 传的是 true ,所以返回值是传入类型零值的指针。
make函数底层实现通过执行以下命令go tool compile -N -l -S file.go
我们可以看到make函数初始化
slice调用的是runtime.makeslice、runtime.makeslice64这两个方法.
编辑切换为居中
添加图片注释,不超过 140 字(可选)
map调用的是runtime.makemap64、runtime.makemap、runtime.makemap_small这三个方法.
chan分别调用的是runtime.makechan64、runtime.makechan这三个方法.