网易首页 > 网易号 > 正文 申请入驻

Golang make和new的区别及实现原理详解

0
分享至

在Go语言中,有两个比较雷同的内置函数,分别是new和make方法,二者都可以用来分配内存,那们有什么区别呢?下面我们就从底层来分析一下二者的不同。感兴趣的小伙伴们可以参考借鉴

前言

在Go语言中,有两个比较雷同的内置函数,分别是new和make方法,二者都可以用来分配内存,那他们有什么区别呢?对于初学者可能会觉得有点迷惑,尤其是在掌握不牢固的时候经常遇到panic,下面我们就从底层来分析一下二者的不同。感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

new的使用

new可以对类型进行内存创建和初始化,其返回值是所创建类型的指针引用,这是与make函数的区别之一。我们通过一个示例代码看下:

func main() {
var a *int
fmt.Println(a) // nil
*a = 123 //panic
fmt.Println(a)
}

通过上面代码可以看出,当我们通过var声明一个变量后打印后输出nil,当我们给这个变量赋值的时候会报错:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10a9043]

综上可以总结出初始化一个指针变量,其值为nil,nil的值是不能直接赋值的。

既然我们知道了没有为其分配内存,那么我们使用new分配一个吧。代码修改后:

func main() {
var a *int
a = new(int)
fmt.Printf("a type is :%T,a point value is :%v,a value is:%v,a size is: %v\n", a, a, *a, unsafe.Sizeof(a))
//a type is :*int,a point value is :0xc00001a0a0,a value is:0,a size is: 8
*a = 123
fmt.Printf("a type is :%T,a point value is :%v,a value is:%v,a size is: %v\n", a, a, *a, unsafe.Sizeof(a))
//a type is :*int,a point value is :0xc00001a0a0,a value is:123,a size is: 8
}

通过以上示例我们可以看到new其返回一个指向新分配的类型为int的指针,指针值为0xc00001a0a0,这个指针指向的内容的值为零(zero value)。通过new进行内存分配就可以对其进行赋值。

底层实现

new函数的签名如下:

func new(Type) *Type

Type是指变量的类型,可以看到new会根据变量类型返回一个指向该类型的指针。

底层调用的是runtime.newobject申请内存空间:

func newobject(typ *_type) unsafe.Pointer {
return mallocgc(typ.size, typ, true)
}

通过调用mallocgc在堆上按照typ.size的大小申请内存,因此new只会为结构体申请一块内存空间,不会为结构体中的指针类型申请内存空间。

make的使用

make 函数也是用于内存分配的,但是和new不同,仅支持 slice、map、channel 三种数据类型的内存创建,其返回值是所创建类型的本身,而不是新的指针引用。

注意:这三种类型都是引用类型,所以没必要返回他们的指针了,必须得初始化,但是不是设置为零值。

我们通过一个示例看一下:

func test() {
var s *[]int
fmt.Printf("s: %p %#v \n", &s, s) //s: 0xc00000e028 (*[]int)(nil)
s = new([]int)
fmt.Printf("s: %p %#v \n", &s, s) //s: 0xc00000e028 &[]int(nil)
(*s)[0] = 8
fmt.Printf("s: %p %#v \n", &s, s) //panic: runtime error: index out of range [0] with length 0
}

我们先用new进行初始化,会给引用类型初始化为nil,nil是不能直接赋值的。下面改为make。

func test() {
var s = make([]int, 5)
fmt.Printf("s: %p %#v \n", &s, s) //s: 0xc00000c060 []int{0, 0, 0, 0, 0}
s[0] = 8
fmt.Printf("s: %p %#v \n", &s, s) //s: 0xc00000c060 []int{8, 0, 0, 0, 0}
}

通过以上示例输出我们可以看到,make不仅可以开辟一个内存,还能给这个内存的类型初始化其零值。同理,对于map、channel也是同样的效果。

底层实现

make函数的签名如下:

func make(t Type, size ...IntegerType) Type

可以看到make返回的是复合类型本身。

make在申请slice内存时,底层调用的是runtime.makeslice,

func makeslice(et *_type, len, cap int) unsafe.Pointer {
mem, overflow := math.MulUintptr(et.size, uintptr(cap))
if overflow || mem > maxAlloc || len < 0 || len > cap {
mem, overflow := math.MulUintptr(et.size, uintptr(len))
if overflow || mem > maxAlloc || len < 0 {
panicmakeslicelen()
}
panicmakeslicecap()
}
return mallocgc(mem, et, true)
}

可以看到makeslice申请内存底层调用的也是mallocgc,首先通过MulUintptr根据容量cap乘以type.siz计算出所需要内存大小,然后再分配所需内存,make为map和channel申请内存底层分别是runtime.makemap_small,runtime.makechan,也是同样调用mallocgc。

总结

make和new都是golang用来分配内存的函数,且在堆上分配内存,make 即分配内存,也初始化内存。new只是将内存清零,并没有初始化内存。
make返回的还是引用类型本身;而new返回的是指向类型的指针。
make只能用来分配及初始化类型为slice,map,channel的数据;new可以分配任意类型的数据。

到此这篇关于深入理解Golang make和new的区别及实现原理的文章就介绍到这了

  • 原文来自:https://www.jb51.net/article/266132.htm
  • 本文地址:https://www.linuxprobe.com/make-new-linux.html编辑:向云艳,审核员:逄增宝
  • Linux命令大全:https://www.linuxcool.com/
  • Linux系统大全:https://www.linuxdown.com/
  • 红帽认证RHCE考试心得:https://www.rhce.net/

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
季后赛生涯首次!威少拉倒东契奇+拳击华盛顿吃两T 携悍将被驱逐

季后赛生涯首次!威少拉倒东契奇+拳击华盛顿吃两T 携悍将被驱逐

醉卧浮生
2024-04-27 10:39:40
曝黎婉华香港豪宅准备出售,70万买升值到30亿,何超贤让外人看房

曝黎婉华香港豪宅准备出售,70万买升值到30亿,何超贤让外人看房

欢乐大意
2024-04-26 23:17:35
没人敢动的军中巨贪,背后有两大保护伞,刘源:丢乌纱帽也拿下他

没人敢动的军中巨贪,背后有两大保护伞,刘源:丢乌纱帽也拿下他

旧时楼台月
2024-04-22 14:42:41
英首相对华发表不当言论,中方回应时,对他改了称呼,事态严重

英首相对华发表不当言论,中方回应时,对他改了称呼,事态严重

易同学爱谈娱乐
2024-04-26 13:01:08
村支书向麦田排污后续!多部门介入,村支书秒怂:上级让我干的

村支书向麦田排污后续!多部门介入,村支书秒怂:上级让我干的

洛洛女巫
2024-04-26 16:26:03
惠州房价腰斩?有网友爆料某房源从挂牌105.5万,到现在的53万…

惠州房价腰斩?有网友爆料某房源从挂牌105.5万,到现在的53万…

火山诗话
2024-04-26 08:00:03
天哪罗志祥的脸太吓人了,满脸的科技感,好像哪里都动过了

天哪罗志祥的脸太吓人了,满脸的科技感,好像哪里都动过了

娱乐八卦木木子
2024-04-26 03:08:07
北京市委书记、市长调研走进车展,与雷军现场交流

北京市委书记、市长调研走进车展,与雷军现场交流

澎湃新闻
2024-04-27 13:46:29
铁血,归来!曝穆里尼奥“三进宫”切尔西!“顶薪先生”将遭驱逐

铁血,归来!曝穆里尼奥“三进宫”切尔西!“顶薪先生”将遭驱逐

头狼追球
2024-04-27 17:28:04
俄罗斯开始恐惧了,在电视台讨论ATACMS将打击哪些俄罗斯城市

俄罗斯开始恐惧了,在电视台讨论ATACMS将打击哪些俄罗斯城市

火星宏观
2024-04-26 15:49:38
穆迪再次下调评级,万科回应:坚决反对,希望准确评估和反映公司情况

穆迪再次下调评级,万科回应:坚决反对,希望准确评估和反映公司情况

澎湃新闻
2024-04-27 15:58:40
笑麻了!南昌连续三次向游客喊话来旅游,网友:不会日语怎么办?

笑麻了!南昌连续三次向游客喊话来旅游,网友:不会日语怎么办?

小白探影8
2024-04-27 15:32:03
一个国家被踢出SWIFT系统的后果非常的严重!

一个国家被踢出SWIFT系统的后果非常的严重!

华夏司马北
2024-04-24 22:01:49
俄罗斯族乌军总司令上任近三个月 作战风格曝光:强调耐心和纪律性,重视无人机使用

俄罗斯族乌军总司令上任近三个月 作战风格曝光:强调耐心和纪律性,重视无人机使用

红星新闻
2024-04-26 18:04:11
降价出售?买华为Pura70的黄牛该哭了

降价出售?买华为Pura70的黄牛该哭了

闲醉山人
2024-04-26 22:47:19
汪峰现身蔚来展台,李斌亲自接待展现高情商,学习雷军营销手段。

汪峰现身蔚来展台,李斌亲自接待展现高情商,学习雷军营销手段。

娱乐圈酸柠檬
2024-04-27 11:26:33
为抗议美国对加沙政策,美国务院发言人辞职

为抗议美国对加沙政策,美国务院发言人辞职

环球时报国际
2024-04-26 14:19:54
侃爷让她穿啥就穿啥,网友:她也愿意的,痛苦并快乐着

侃爷让她穿啥就穿啥,网友:她也愿意的,痛苦并快乐着

三月柳
2024-04-13 15:27:23
60岁女人再过夫妻生活,3位女人说出了真心话

60岁女人再过夫妻生活,3位女人说出了真心话

胥洋洋爱唱歌
2024-04-07 04:14:14
2000亿,北京首富宣告破产

2000亿,北京首富宣告破产

融资中国
2024-04-27 10:55:09
2024-04-27 19:14:44
孙有匪
孙有匪
科技
1595文章数 2009关注度
往期回顾 全部

科技要闻

特斯拉这款车型刚上市几天,就上调价格

头条要闻

去世半年前 90岁老太被摄影师外孙女爆改成"19岁少女"

头条要闻

去世半年前 90岁老太被摄影师外孙女爆改成"19岁少女"

体育要闻

时代要落幕了?詹姆斯杜兰特陷0-3绝境

娱乐要闻

金靖回应不官宣恋情结婚的原因

财经要闻

北京房价回到2016年

汽车要闻

5月上市/智能化丰富 海狮 07EV正式到店

态度原创

艺术
家居
时尚
教育
军事航空

艺术要闻

画廊周北京迎来第八年, “漂留” 主题聚集 30 余家艺术机构与 40 场展览

家居要闻

光影之间 空间暖意打造生活律动

七八十岁男人,尽量别穿“背心+大裤衩”出门,显老油腻、很邋遢

教育要闻

闹大了!公务员聘用全是有留英背景的毕业生,网友纷纷质疑合理性

军事要闻

佩洛西称俄在支持"挺巴"的美国反战学生 扎哈罗娃回应

无障碍浏览 进入关怀版