概述

Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似。不过解释两者之间的不同也非常容易。 他们所做的事情,和应用的类型也不相同。 
二者都是用来分配空间。

new 函数

  • new 是内建函数,函数原型为
func new(Type) *Type
  • 1

官方文档描述为:

The new build-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. 
翻译如下: 
内置函数 new 分配空间。传递给new 函数的是一个类型,不是一个值。返回值是 指向这个新分配的零值的指针。

根据这段描述,我们也可以自己实现一个类似 new 的功能

    func newInt *int {
var i int
return &i //为何可以返回局部变量呢?
}
someInt := newInt()
  • 1
  • 2
  • 3
  • 4
  • 5

这里要注意的第一点是,返回值是一个指针。 
然后,为何一个golang 中的函数可以返回局部变量呢?

make 函数

make 也是内建函数,你可以从 http://golang.org/pkg/builtin/#make 看到它, 它的函数原型 比 new 多了一个(长度)参数,返回值也不同。 
函数原型是:

func make(Type, size IntegerType) Type 
  • 1
  • 第一个参数是一个类型,第二个参数是长度
  • 返回值是一个类型

官方描述为:

The make built-in function allocates and initializes an object(分配空间 + 初始化) of type slice, map or chan**(only)**. Like new , the first arguement 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. 
翻译为: 
内建函数 make 分配并且初始化 一个 slice, 或者 map 或者 chan 对象。 并且只能是这三种对象。 和 new 一样,第一个参数是 类型,不是一个值。 但是make 的返回值就是这个类型(即使一个引用类型),而不是指针。 具体的返回值,依赖具体传入的类型。

Slice : 第二个参数 size 指定了它的长度,此时它的容量和长度相同。
你可以传入第三个参数 来指定不同的容量值,但是必须不能比长度值小。
比如: make([]int, 0, 10)
Map: 根据size 大小来初始化分配内存,不过分配后的 map 长度为0。 如果 size 被忽略了,那么会在初始化分配内存的时候 分配一个小尺寸的内存。
Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者被 忽略,管道是没有缓冲区的。
  • 1
  • 2
  • 3
  • 4
  • 5

var p *[]int = new([]int) 
var v []int = make([]int, 10) 
上述第一条语句 使用 new() 函数为 切片结构分配内存,*p == nil (这意味着什么? 意味着没有对Slice结构进行初始化), 但是在实际中这种用法很少使用。 
第二条语句使用 make() 函数创建了一个有10个元素的 Slice对象。

总结

new 的作用是 初始化 一个指向类型的指针 (*T), make 的作用是为 slicemap 或者 channel 初始化,并且返回引用 T

make(T, args)函数的目的与new(T)不同。它仅仅用于创建 Slice, Map 和 Channel,并且返回类型是 T(不是T*)的一个初始化的(不是零值)的实例。 这中差别的出现是由于这三种类型实质上是对在使用前必须进行初始化的数据结构的引用。 例如, Slice是一个 具有三项内容的描述符,包括 指向数据(在一个数组内部)的指针,长度以及容量。在这三项内容被初始化之前,Slice的值为nil。对于Slice,Map和Channel, make()函数初始化了其内部的数据结构,并且准备了将要使用的值。

问题:栈中分配的变量,出栈的时候不会被释放吗?

我们注意到有如下函数:

    func newInt *int {
var i int
return &i //为何可以返回局部变量呢?
}
someInt := newInt()
  • 1
  • 2
  • 3
  • 4
  • 5

有个回答回答的很好: golang 和 c 语言不一样,栈区分配的存储空间不会随着函数的返回而释放,本地变量地址所占据的存储空间会生存下来。

New & make in go_Code的更多相关文章

  1. golang笔记——IDE

    可选方案有 Lite IDE\GoSublime\Visual Studio Code\Goclipse\Vim 1.Lite IDE 这是国人开发的开源且跨平台的 golang 专属IDE,也算是目 ...

  2. Go 语言学习

    golang中国 http://www.golangtc.com/ 第三方github学习 https://github.com/Unknwon/go-fundamental-programmingh ...

  3. C语言和go语言之间的交互

    一.go代码中使用C代码 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import "C" 即可在go代码中使用C函数 代码示例: go代码:tes ...

  4. java中集合Collection转list对象

    参考:java中集合Collection转list对象 首先我的需求是获取到购物车列表,购物车列表是一个Map对象,构造方法获取购物项,这里购物项是Collection对象 // 购物项集合,K商品I ...

  5. ubuntu下c/c++/python/go编译运行

    C语言: .c文件 编译器gcc//my_code下hello.c文件 $sudo apt install gcc $gcc hello.c -o hello $./hello C++: .cpp文件 ...

  6. C语言和go语言之间的交互 - C语言中使用go语言,使用的go语言又使用了c语言

    一.go语言中使用C语言 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import “C” 即可在go代码中使用C函数 代码示例: go代码:testC.go 1 pa ...

  7. (四十四)golang--协程(goroutine)和管道(channel)相结合实例

    统计1-8000之间的素数. 整体框架: 说明:有五个协程,三个管道.其中一个协程用于写入数字到intChan管道中,另外四个用于取出intChan管道中的数字并判断是否是素数,然后将素数写入到pri ...

  8. golang数据结构之队列

    队列可以用数组或链表实现,遵从先入先出. 目录结构: 在main中调用queue包中的属性和方法,如何调用参考另一篇文章: https://www.cnblogs.com/xiximayou/p/12 ...

  9. golang数据结构之循环链表

    循环链表还是挺有难度的: 向链表中插入第一条数据的时候如何进行初始化. 删除循环链表中的数据时要考虑多种情况. 详情在代码中一一说明. 目录结构如下: circleLink.go package li ...

随机推荐

  1. c#: 剪切板监视实现

    CR TubeGet中有用户需要剪切板监视功能,记录代码以做备忘: using System; using System.Runtime.InteropServices; using System.W ...

  2. JQuery学习笔记之选择器

    JQuery与DOM对象 <div id="test1" class="test2"></div> DOM对象获取方式: var dom ...

  3. MoveIt简单编程

    目的:使用一些简单代码使机器人运动到指定位置.讲解代码怎么实现机器人的运动. 参考文献: 第一个博客需要下载<Mastering ROS for robotics Programming> ...

  4. sublime设置默认字体样式

    因电脑配置的不同,还有个人喜好的不同,有时候想用自己喜欢的字体来写代码,想用自己习惯的字号大小来显示代码.这些又该怎样设置呢? 本节主要介绍下如何设置字体大小和样式 (1)点菜单栏 “Preferen ...

  5. DT系统应用-添加地图标注

    修改方法:修改模板->Homepage->contact.htm 在 {php $map_height = 300;} {php @include DT_ROOT.'/api/map/'. ...

  6. iOS 开发,相关网址

    iOS 开发,相关网址 说明 网址 注册开发者 https://developer.apple.com/cn/programs/enroll/ 未付费688个人开发账号真机调试测试教程 http:// ...

  7. python预课06 基于百度大脑AI的人工智能,百度颜值检测,语音合成与识别

    百度大脑: 如下图,百度开放了许多人工智能接口可以使用,先注册一个百度大脑账户 点击创建应用,选择需要的功能,如人脸识别,语音识别等 点击查看文档,可以查看功能对应语言的方法,参数.首先在CMD命令下 ...

  8. input提示字在有焦点消失或输入改变时消失

    一:获取焦点时 提示字消失 <input type="text" name="textfield" value="这里是提示内容" o ...

  9. log4j2 配置文件解读

    1.日志相关介绍 日志接口(slf4j):slf4j是对所有日志框架制定的一种规范.标准.接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用,比如log4j.l ...

  10. 【每天学一点Linux】centos7 docker 启动cpu100% 飙升居高不下 无法关机 无法杀死进程

    目前不知道什么原因. 重装了docker后仍然不行.安装方式为yum(在线和本地方式). 后来使用了下载static压缩包的方式来使用,就没有再出现如题的问题了.安装包地址为:https://down ...