golang 中有两个内置函数可以用来在堆上分配内存,分别是 mak() 和 new(),这篇文章中会简要介绍下这两个函数的区别,以及这两个函数分别在什么情况下使用。

下面先看下 golang 中对这两个内置函数的定义。

new():

func new(Type) *TypeThe 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.

make();

func make(t Type, size ...IntegerType) TypeThe 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.

从上面两个函数的定义,我们可以看到两个明显的区别。

区别一:接收的参数个数不一样

从 new() 函数的定义可以看到,它只接收一个参数 —— Type,即要为哪种类型分配内存。

而从 make() 函数的定义可以看到,它可以接收多个参数,第一个参数也是 Type,剩下的是可选的整数类型参数。

make() 函数可以为 slice 类型分配内存,当 make() 函数为 slice 类型分配内存时,可选的整型参数可以用来指定 slice 的 length 和 capacity,示例如下:

package mainimport ("fmt"
)func main() {my_slice := make([]int, 5, 10)fmt.Println(my_slice)
}

运行上面的程序,会得到如下输出结果:

[0 0 0 0 0]

可以看到,golang 为我们分配了一个长度为 5 的 slice。

区别二:返回类型不一样

new() 函数返回一个指向接收参数类型的指针。

make() 函数返回类型和它接收的第一个参数类型一样。

下面我们通过一个例子来验证这一点:

package mainimport ("fmt"
)func main() {new_int := new(int)fmt.Printf("new_int type: %T\n", new_int)make_slice := make([]int, 5)fmt.Printf("make_slice: %T\n", make_slice)
}

运行上面的程序,输出结果如下:

new_int type: *int
make_slice: []int

可以看到,new_int 的类型是一个指向int类型的指针;而 make_slice 是一个包含int类型的 slice。

区别三:应用场景不一样

make() 函数专门用来为 slice、map、chan 来分配内存并做初始化的;而 new() 更像是一个通用的内存分配工具,可以为其他类型分配内存。

上面说到 new() 更像是一个通用的内存分配工具,但是它不可以为 slice、map、chan 这种引用类型来分配内存。这是因为 new() 只是简单的分配内存,并在内存上根据类型做零值(zero value)处理。

像slice、map、chan这样的引用类型,在创建这样类型的值后,会创建一个称作 header 的值,它其实是一个数据结构,这个数据结构中,包含一个指向底层数据结构的的指针,另外根据引用类型的不同,还会包含不同的字段用来管理底层数据结构。

以 slice 类型为例,当创建一个 slice 类型的值时,会创建一个轻量级的数据结构,这个数据结构包含三个字段:pointer、length、capacity。

  • pointer 是一个指向底层数组(underly array)的指针。
  • length 代表 slice 的长度
  • capacity 代表 slice 的容量

由此可以看到为什么不能用 new() 来创建 slice、map、chan 这样的引用类型了。如果用 new() 来创建 slice,那么创建的 header 中的 pointer 做0值处理,就会被初始化为 nil,而 length 和 capacity 也会被初始化为0,这样显然是不正确的。

总结

new() 和 make() 都是 golang 中用来分配内存的函数,本文介绍了 make() 和 new() 的三个主要的区别:

  • 接收参数个数不一样:new() 只接收一个参数,而 make() 可以接收多个参数
  • 返回类型不一样:new() 返回一个指针,而 make() 返回类型和它接收的第一个参数类型一样
  • 应用场景不一样:make() 专门用来为 slice、map、chan 这样的引用类型分配内存并作初始化,而 new() 用来为其他类型分配内存。

一如既往,如果你对文章中的内容有任何疑问,或者是发现文章中有任何错误,都可以通过留言告诉我;如果你喜欢我的文章,欢迎关注我的微信公众号 Tech For Geek。

golang: make 与 new 的区别相关推荐

  1. Golang与C#之switch区别

    2019独角兽企业重金招聘Python工程师标准>>> Golang与C#之switch区别 Go是Google开发的一种编译型,可并行化,并具有垃圾回收功能的编程语言. C#是微软 ...

  2. Golang make和new的区别详解

      目录 一.new 二.make 三.new 和 make的区别 许多小伙伴在刚接触 Golang 的时候不理解为什么会有两个用于分配内存的函数: new 和 make,俗话说:存在即合理,下面就来 ...

  3. go语言和python的区别_golang和python有什么区别?

    golang和python有什么区别?下面本篇文章给大家对比一下Python和Golang,介绍一下golang和python的区别.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. ...

  4. Go | Go和Java区别

    0. Java Go区别 精简版: 0.1 语法 0.1.1 访问权限 Java使用public.protected.private.默认等几种修饰符来控制访问权限: golang通过大小写控制包外可 ...

  5. go与python作为后端_golang和python有什么区别?_后端开发

    golang吉祥物是啥?_后端开发 golang吉祥物是一只英文名为"gopher"的地鼠(土拨鼠),大大的眼睛,圆圆的身子,短短的手. golang和python有什么区别?下面 ...

  6. go与python区别_golang和python有什么区别?

    golang和python有什么区别?下面本篇文章给大家对比一下Python和Golang,介绍一下golang和python的区别.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. ...

  7. go-内存管理篇(二) 万字总结-golang内存分配篇

    前言 本文是讲解Golang内存管理的第二篇,在第一篇中我们提到,Golang的内存分配模式与TCMalloc是极其相似的. 所以先来回顾一下TCMalloc相关知识点. Page:TCMalloc也 ...

  8. Go语言入门指南,带你轻松学Go

    Go(Golang) 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发, ...

  9. channelinactive触发后不关闭channel_golang chan 最详细原理剖析,全面源码分析!看完不可能不懂的!...

    大纲 channel 是什么? channel 使用姿势 chan 创建 chan 入队 chan 出队 结合 select 语句 结合 for-range 语句 源码解析 `makechan` hc ...

最新文章

  1. 使用密码记录工具keepass来保存密码
  2. 第14课:项目实战——深度优化你的神经网络模型
  3. 流水线、超流水线、超标量技术对比
  4. python 数据框缺失值_Python:处理数据框中的缺失值
  5. IDA python 脚本编程使用参考资料链接
  6. 备份自己常用的VS2010设置
  7. 饱和气压与温度的关系_高中物理讲义:固体液体与物态变化第3节《饱和汽与饱和汽压》...
  8. com和dll(一)
  9. Linux内核启动中驱动初始化过程
  10. GPS、RTK、PPK三种定位技术的原理及应用
  11. EDA课程设计(设计一个4时隙的时分复用模块)
  12. [转]DSP2812 代码段(.text段)太长的解决办法——通过cmd文件拆分.text段
  13. XCTF-2020CyBRICS部分逆向
  14. html表格打印自动换行,html 表格自动换行问题
  15. Si24R2F+2.4GHz ISM 频段低功耗无线集成嵌入式发射基带无线发射芯片
  16. wince模拟器上网_wince5.0模拟器下载
  17. 统计学 多元线性回归
  18. 全球及中国红外探测器芯片行业发展动态及投资应用前景调研报告2021-2027年
  19. 印象笔记粘贴HTML,【未解决】Mac中从印象笔记中拷贝图片后去VSCode中用Paste Image无法粘贴图片:There is not a image in clipboard...
  20. 女性如何理解男人的性需求? 男性的性表达

热门文章

  1. 显卡光线追踪是什么?怎么判断性能高低?
  2. Linux零基础从入门到精通,必学的55个指令合集【上篇】
  3. 中国人民公安大学信息技术与网络安全学院 《网络攻击与防御》
  4. 利用华为云ECS服务器搭建安防视频监控平台【华为云至简致远】
  5. Session会在关闭浏览器的时候自动清空吗?
  6. 如何给女友挑选黑丝?用Python来分析一波哪一款好看
  7. 【Django采用cors跨域收不到POST请求】
  8. smbd cpu高 linux,samba – smbd进程在不间断的睡眠中
  9. Adavanced Installer 用户自定义行为——卸载时删除残留日志文件
  10. asp毕业设计——基于asp+sqlserver的个人日志系统设计与实现(毕业论文+程序源码)——个人日志系统