Go 语言中的 new() 和 make()的区别
本文是看了文章之后的心得。 在此感谢。
概述
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 的作用是为 slice, map 或者 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 语言不一样,栈区分配的存储空间不会随着函数的返回而释放,本地变量地址所占据的存储空间会生存下来。
那么: 什么时候会释放呢? 什么情况下才会释放呢? (好问题,今天我一定回答了)
Go 语言中的 new() 和 make()的区别的更多相关文章
- C语言中 *.c和*.h文件的区别!
C语言中 *.c和*.h文件的区别! http://blog.163.com/jiaoruijun07@126/blog/static/68943278201042064246409/ ...
- C语言中字符型和字符串型的区别?
C语言中只有字符型类型,没有字符串型类型.字符类型用一个带符号的8位二进制编码表示,其性质与int相同,只是只有一个字节.表示字符的ASCII编码使用其中的0~127,所以要明白字符类型(char)其 ...
- (十一)C语言中内存堆和栈的区别
在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认 ...
- 别人不会给你说的---C语言中数组名和指针的区别 及 sizeof用法
引自: http://blog.csdn.net/tianyue168/article/details/5781924 #i nclude <iostream.h> int main( ...
- c语言中 *p++ 和 (*p)++ 有什么区别?以及C语言运算符的优先级。整理。
*p++是指下一个地址. (*p)++是指将*p所指的数据的值加一. C编译器认为*和++是同优先级操作符,且都是从右至左结合的,所以*p++中的++只作用在p上,和*(p++)意思一样:在(*p)+ ...
- C C语言中 *.c和*.h文件的区别!
一个简单的问题:.c和.h文件的区别学了几个月的C语言,反而觉得越来越不懂了.同样是子程序,可以定义在.c文件中,也可以定义在.h文件中,那这两个文件到底在用法上有什么区别呢? 2楼:子程序不要定义在 ...
- Django与SQL语言中——NULL与空字符串的区别
SQL有指定空值的独特方式,它把空值叫做NULL. Null在数据库中表示 不知道的数据,主要有3种意思: 1)知道数据存在,但不知道具体值. 2)不知道数据是否存在. 3)数据不存在. 在SQL中, ...
- 【转】C语言中数组名和指针的区别
注:本文转自http://www.cnblogs.com/furaibo/archive/2010/03/19/1689710.html 魔幻数组名 请看程序(本文程序在WIN32平台下编译): #i ...
- C语言中的变量和常量的区别和使用
变量 定义一个变量:类型 变量名=值; int a =0; // 变量,可以在赋值 常量 定义一个常量 const 常量类型 常量名称 = 值 const int LENTHER = 521 // 定 ...
随机推荐
- <td>内容超出自动换行
td 内容自动换行 table表格td设置宽度后文字太多自动换行 设置table 的 style="table-layout:fixed;" 然后设置td的 style=" ...
- 第10月第28天 touchesBegan hittest
1. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [[self nextResponder] touchesBe ...
- 第7月第19天 swift on linux
1. https://github.com/iachievedit/moreswift http://dev.iachieved.it/iachievedit/more-swift-on-linux/ ...
- MapReduce--shuffle
一.Shuffle简介 Shuffle的正常意思是洗牌或弄乱,shuffle的大致范围就是把map task的输出结果有效的传送到Reduce端.也可以这样理解,shuffle描述着数据从map ta ...
- 从TFS 删除工作项
一.进入命令执行窗口的方式 1.若你的TFS服务器上安装了VS开发工作,可以按以下步骤,进入命令行方式,图如下: 2.若你TFS上没有安装VS开发工作,可以从你的开发机器上的VS安装目录下(一般情况下 ...
- poj2049
优先队列广搜,有人说用SPFA,不知道怎么做的 #include <cstdio> #include <queue> #include <cmath> #inclu ...
- 解决urbuntu桌面本客户端输入ll command not found
用桌面版的urbuntu系统,打开客户端输入ll,报错如下 于是度娘,解决方案:可以作如下修改:打开 ~/.bashrc 找到 #alias ll=’ls -l’,去掉前面的#就可以了.(关闭原来的终 ...
- django orm按天统计发布单数量
夜深了,先上代码和数据,明天再实现可视化图表. from datetime import datetime, timedelta from django.http import JsonRespons ...
- linux修改文件读写执行权限命令chmod
之前用chmod的时候都是简单的类似下面这样使用: $ file 也有时候可能会修改一个目录下所有子目录和文件: $ directory -R 也知道3个数字(例子中的755)分别代表赋予 “文件属主 ...
- Eclipse 之开发环境的常用配置
一.Java智能提示 (1). 打开Eclipse,选择打开" Window - Preferences". (2). 在目录树上选择"Java-Editor-Conte ...