当前位置: 首页 > 科技观察

说说Golang的make和new函数

时间:2023-03-19 23:18:04 科技观察

今天在说make和new函数之前,先来看一个现象。当然,如果你对golang的指针不是很了解,可以先看这篇文章,做到无缝衔接。看完这篇,我彻底明白了golang的指针。case1varainta=1fmt.Println(a)//返回结果//1这个例子很简单,我们定义了一个int类型的变量,然后赋值直接输出,这个不用怀疑,但是我们换个例子看看case2varp*int*p=10fmt.Println(*p)上面的代码会输出什么?毫不奇怪,它会输出10,对吗?但是我们运行之后,命令行输出panic:runtimeerror:invalidmemoryaddressornilpointerdereference[signalSIGSEGV:segmentationviolationcode=0x2addr=0x0pc=0x10428df44]goroutine1[running]:main.main()为什么这是?简单说一下原因:因为我们在varp*int中,只是将p变量定义为指针类型,p的默认值为nil,“内存中没有分配相应的空间”,因为没有空间,然后给p变量赋值,自然会报错。当然p还是占空间的,只是p的值为nil。如果我们把代码改成下面这样:varp*int=new(int)*p=10fmt.Println(*p)//Outputresults//10个结果可以正常输出,为什么添加后可以正常输出新的?要回答这个问题,首先你得知道这个新函数是干什么的。新函数主要做了以下三件事:调用操作系统接口申请一个int类型的内存空间。操作系统将分配的空间返回给go程序,在内存中开辟一个int空间,将这个空间的指针指向p,因为现在指针p已经指向了一个分配的空间,所以可以进行赋值操作直接总结对于int、string、float、rune、byte、bool等类型,系统在定义变量的时候就已经申请了内存,并赋予了相应的默认值(int的默认值为0,string的默认值为"",bool的默认值为false),所以我们可以直接给变量赋值。对于指针、切片、映射等类型,直接定义这些变量时系统是不分配内存的,默认值为nil,所以不能直接赋值。如果要赋值,需要使用new或者make函数提前向系统申请内存。make和new的区别make和new都是用来分配内存的。简单的说,new只是分配内存。“make用于slice、map、channel的初始化,它不仅可以开辟一块内存,还可以把这块内存的类型初始化为它的零值”。make返回引用类型本身;new返回指向该类型的指针。makefuncmake(tType,size...IntegerType)Typenewfuncnew(Type)*Typemake只能用于分配和初始化slice、map、channel类型的数据;new可以分配任何类型的数据。