new()和make()的区别--go语言

有的时候容易将new()和make()弄混,他们都是在为变量分配内存空间时用到的,但是他们其实有很大的不同,我们结合例子说明一下

new()

new()是go语言的内建函数,他的声明如下

func new(Type) *Type

解析一下就是,内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配类型零值的指针

什么时候会用到呢,我们看一下下面的例子

package main

import "fmt"

func main(){
	var i *int
	*i=10
	fmt.Println(*i)

C:\Users\my\go\src\hello>go run test.go
panic: runtime error: invalid memory address or nil pointer dereference

很明显出错了,这也是一个常见的错误,无效的内存地址或者空指针,很明显找不到*i的地址,这时候就需要new()了

func main(){
	var i *int
	i=new(int)
	*i=10
	fmt.Println(*i)
}

C:\Users\my\go\src\hello>go run test.go
10


OK,完美解决

make()

make()也是内建函数,他比new()多了一个参数,并且返回的类型改变

func make(Type, size IntegerType) Type

官方文档对他说明:内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型

Slice: 第二个参数 size 指定了它的长度,它的容量和长度相同。
你可以传入第三个参数来指定不同的容量值,但必须不能比长度值小。
比如 make([]int, 0, 10)
Map: 根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存

Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者忽略容量,管道是没有缓冲区的

他的用法如下:

func main(){
    arr:=[]int{}
	arr[0]=1
	fmt.Println(arr)
}

C:\Users\my\go\src\hello>go run test.go
panic: runtime error: index out of range


直接赋值就报错,溢出了
这种问题解决的方法有两种:

func main(){
    arr:=make([]int,5)
	arr[0]=1
	fmt.Println(arr)
}
func main(){
    arr:=[]int{}
	arr=append(arr,1)
	fmt.Println(arr)
}

上面这两种都能解决这个问题

总结:

new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。
希望大家不会用错。

猜你喜欢

转载自blog.csdn.net/LYue123/article/details/88924153