文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

golang中new与make的区别讲解

2023-01-12 15:00

关注

new和make

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

对于官方是这么解释new的:这个内置函数功能是分配内存。第一个参数是一个自定义类型,并不是一个值,返回值为一个指向新分配好的内存空间的一个指定类型指针,并且这个内存空间会被清零(也就是变为该类型的零值)。

使用new初始化

至于使用new进行初始化,根据语言规范:The built-in function new takes a type T and returns a value of type *T. The memory [pointed to] is initialized as described in the section on initial values.因为go中的函数不能被重载,并且这不是可变参数,所以无法传递任何初始化数据。 取而代之的是,go将使用对类型和任何成员字段适当的任何0版本进行初始化。

零值

go语言总共分为四大类型:基本数据类型、复杂数据类型、引用数据类型和接口类型。零值是指基本数据类型和指针的初始值。
数值型零值为0、string的零值为""、bool的零值为false、指针的零值为nil

使用示例(new也可以为数组分配内存)

 a := new(int)
 fmt.Printf("类型为:%T, 值为:%v\n", a, a)
 fmt.Printf("类型为:%T, 值为:%v\n", *a, *a)
 b := new(string)
 fmt.Printf("类型为:%T, 值为:%v\n", b, b)
 fmt.Printf("类型为:%T, 值为:%v\n", *b, *b)
 c := new(*int)
 fmt.Printf("类型为:%T, 值为:%v\n", c, c)
 fmt.Printf("类型为:%T, 值为:%v\n", *c, *c)
 
 运行结果:
 类型为:*int, 值为:0xc0000a6058
 类型为:int, 值为:0               
 类型为:*string, 值为:0xc000088220
 类型为:string, 值为:             
 类型为:**int, 值为:0xc0000ca020  
 类型为:*int, 值为:<nil>  

new(struct)和&struct{}区别

因为struct{}这种操作可以对类型进行初始化,并且基于上述new的理解之后就会发现&struct{}new(struct)其实这两种声明方式几乎没有区别。但我们在项目中经常会使用到这两种操作,就自然会想这两者的区别(跟本人一样)。

在我调查了一些资料后,我个人觉得他们唯一的区别就在于new只能声明一个零值的该类型的指针并返回,但是&struct{}可以在声明的同时进行初始化操作。

func main(){
	A := new(struct) // 只能返回一个struct的指针
	B := &struct{Id:1,Name:"张三"} // 可以返回一个带有默认值的struct的指针
}

上述例子就很好的说明了这个问题。

小结

new只能开辟单个空间,不能为引用类型开辟多个空间。并且new是对类型进行内存的开辟,返回一个指向该内存空间的指针类型。如果使用new去初始化引用数据类型,不是很合适(当然,new一个对象还是可以的)。因此就需要用到另一个内置函数make。

make

// The make built-in function allocates and initializes an object of type // slice, map, or chan (only). Like new, the first argument is a type, not a // value. Unlike new, make's return type is the same as the type of its // argument, not a pointer to it. The specification of the result depends on // the type:
func make(t Type, size ...IntegerType) Type

对于官方是这么解释make的:该函数功能是分配内存并且初始化一个切片(slice/map/channel)类型的对象。相比较内置函数new而言,make的第一个参数也是一个自定义类型,不是一个值。但make的返回类型是一个和他传入的自定义参数类型完全相同的类型。并不是一个指针去指向这个新开辟的内存空间。

make 也是用于内存分配的,但是和 new 不同,它只用于 chan、map 以及 slice 的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

简述make的初始化(slice/map/channel)

在这里插入图片描述

make在对slice/map/channel这三种类型进行初始化时,在编译初期阶段,go语言就已经将代表make关键字的OMAKE节点根据参数类型的不同转换成了OMAKESLICE、OMAKEMAP、OMAKECHAN三种不同类型的节点。这些不同的节点最终会调用不同的运行时函数来初始化数据结构。

使用示例

var a []int
fmt.Println(a[0])
// 运行结果
panic: runtime error: index out of range [0] with length 0

如果不对切片进行初始化,就无法使用

 var a []int
 a = make([]int, 1)
 fmt.Println(a[0])

mapchan也同理。切片需要指定长度大小,容量可以自动扩容。如果下标超出指定的长度也会出现数组越界的情况。但是map不会发生该情况。即使初始化map容量为0map底层也会自动进行扩容。对于channel来说初始化容量就是初始化缓冲区长度。

总结:

makenew共同点都是可以开辟内存空间,给变量分配内存。
不同点在于:

简单的说,new只分配内存,make用于slice,map,和channel的初始化,并且不返回指针。要获得一个显式的指针,使用new进行分配,或者显式地使用一个变量的地址。

参考资料

go语言中文网
深入学习golang

到此这篇关于golang中new与make的区别的文章就介绍到这了,更多相关golang中new与make的区别内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯