关键点
1、
分配内存
的内置函数是new
和make
2、new 方式 分配内存,
并不常用
,一般使用短式和结构体字面量
的方式3、new 不能用于
map
,channel
,切片
的声明4、
new 分配
时,接收
的是类型
,返回的是该类型的指针
,并且默认
初始化
了5、
make 分配
后,没有初始化
,需要显示初始化
6、make 分配内存后,返还的是该
类型
7、make的使用场景
? 下面三个进行声明
和初始化
时用
channel
切片
map
8、sync.Map, 以及 sync.Mutex 这两个可以直接 通过var来声明变量,
不需要 初始化
var map2 sync.Map
var mu sync.Mutex,
可以直接使用map2, mu变量,操作
9、普通变量,声明后,
就有默认的初始化值
,可以直接
使用10、引用类型,需要
声明
、分配内存
两步;如果只是
声明,操作时会抛异常
1、前言
本文主要给大家介绍了Go语言中函数new与make的使用和区别,
关于Go语言中new和make是内建的两个函数,主要用来创建分配类型内存。
在我们定义生成变量的时候,可能会觉得有点迷惑,其实他们的规则很简单,
下面我们就通过一些示例说明他们的区别和使用,话不多说了,来一起看看详细的介绍吧。
2、变量的声明
var I int
var s string
变量的声明
我们可以通过var关键字
,然后就可以在程序中使用。
当我们不指定变量的默认值时,这些变量的默认值是他们的零值,
比如int类型的零值是0,string类型的零值是"",引用类型的零值是nil。
对于例子中的两种类型的声明,我们可以直接使用,对其进行赋值输出。
但是如果我们换成引用类型呢?
package main
import (
"fmt"
)
func main() {
var i *int
*I=10
fmt.Println(*i)
}
从这个提示中可以看出,对于引用类型的变量
,我们不光要声明
它,还要为它分配内寸空间
,否则我们的值放在哪里去呢
?
这就是上面错误提示的原因。
对于值类型的声明不需要
,是因为已经默认帮我们分配好了
。
要分配内存,就引出来今天的new和make。
3、new 方式
对于上面的问题我们如何解决呢?
既然我们知道了没有为其分配内存,那么我们使用new分配一个吧。
func main() {
var i *int
i=new(int)
*I=10
fmt.Println(*i)
}
现在再运行程序,完美PASS,打印10。
现在让我们看下new这个内置的函数。
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
它只接受一个参数,这个参数是一个类型
,分配好内存后,返回一个指向该类型内存地址的指针
。
同时请注意它同时把分配的内存置为零
,也就是类型的零值
。
我们的例子中,如果没有*i=10,那么打印的就是0。
这里体现不出来new函数这种内存置为零的好处,我们再看一个例子。
package main
import (
"sync"
"fmt"
)
type user struct {
lock sync.Mutex
name string
age int
}
func main() {
u := new(user)
u.lock.Lock()
u.name = "张三"
u.lock.Unlock()
fmt.Println(u)
}
示例中的user类型中的lock字段我
不用初始化
,直接
可以拿来用
,
不会
有无效内存
引用异常
,因为它已经被零值
了。
这就是new,它返回的永远是类型的指针
,指向分配类型的内存地址
。
4、make 方式
make也是用于
内存分配
的,但是和new不同,它只用于
chan、map以及切片的内存创建
,而且它返回的类型就是这三个
类型本身
,-
而不是他们的指针类型,
- 因为这三种类型就是
引用类型
,所以就没有必要
返回他们的指针
了。
- 因为这三种类型就是
注意,因为这三种类型是引用类型
,所以必须
得初始化
,
但是不是置为零值,这个和new是不一样的。
func make(t Type, size ...IntegerType) Type
从函数声明中可以看到,返回的还是该类型
。
5、new 与 make的不同点
所以从这里可以看的很明白了,二者都是内存的分配(堆上)
,
但是make只用于slice、map以及channel的初始化(非零值)
;
而new用于类型的内存分配
,并且内存置为零
。
所以在我们编写程序的时候,就可以根据自己的需要很好的选择了。
make返回的还是这三个引用类型本身;
而new返回的是指向类型的指针
。
6、其实new 不常用
所以有new这个内置函数,可以给我们分配一块内存让我们使用,
但是现实的编码中,它是不常用的
。
我们通常都是采用短语句声明
以及结构体的字面量
达到我们的目的,
比如:
I:=0
u:=user{}
这样更简洁方便,而且不会涉及到指针这种比麻烦的操作。
make函数是无可替代的,我们在使用slice、map以及channel的时候,
还是要使用make进行初始化
,然后才才可以对他们进行操作。