本文是看了文章之后的心得。 在此感谢。

概述

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 语言不一样,栈区分配的存储空间不会随着函数的返回而释放,本地变量地址所占据的存储空间会生存下来。

那么: 什么时候会释放呢? 什么情况下才会释放呢? (好问题,今天我一定回答了)

Go 语言中的 new() 和 make()的区别的更多相关文章

  1. C语言中 *.c和*.h文件的区别!

    C语言中 *.c和*.h文件的区别!  http://blog.163.com/jiaoruijun07@126/blog/static/68943278201042064246409/        ...

  2. C语言中字符型和字符串型的区别?

    C语言中只有字符型类型,没有字符串型类型.字符类型用一个带符号的8位二进制编码表示,其性质与int相同,只是只有一个字节.表示字符的ASCII编码使用其中的0~127,所以要明白字符类型(char)其 ...

  3. (十一)C语言中内存堆和栈的区别

    在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认 ...

  4. 别人不会给你说的---C语言中数组名和指针的区别 及 sizeof用法

    引自: http://blog.csdn.net/tianyue168/article/details/5781924 #i nclude <iostream.h> int  main( ...

  5. c语言中 *p++ 和 (*p)++ 有什么区别?以及C语言运算符的优先级。整理。

    *p++是指下一个地址. (*p)++是指将*p所指的数据的值加一. C编译器认为*和++是同优先级操作符,且都是从右至左结合的,所以*p++中的++只作用在p上,和*(p++)意思一样:在(*p)+ ...

  6. C C语言中 *.c和*.h文件的区别!

    一个简单的问题:.c和.h文件的区别学了几个月的C语言,反而觉得越来越不懂了.同样是子程序,可以定义在.c文件中,也可以定义在.h文件中,那这两个文件到底在用法上有什么区别呢? 2楼:子程序不要定义在 ...

  7. Django与SQL语言中——NULL与空字符串的区别

    SQL有指定空值的独特方式,它把空值叫做NULL. Null在数据库中表示 不知道的数据,主要有3种意思: 1)知道数据存在,但不知道具体值. 2)不知道数据是否存在. 3)数据不存在. 在SQL中, ...

  8. 【转】C语言中数组名和指针的区别

    注:本文转自http://www.cnblogs.com/furaibo/archive/2010/03/19/1689710.html 魔幻数组名 请看程序(本文程序在WIN32平台下编译): #i ...

  9. C语言中的变量和常量的区别和使用

    变量 定义一个变量:类型 变量名=值; int a =0; // 变量,可以在赋值 常量 定义一个常量 const 常量类型 常量名称 = 值 const int LENTHER = 521 // 定 ...

随机推荐

  1. Javascript - LayUI库的流加载

    LayUI库的流加载 用的LayUI-v2.2.45,将整个包解压缩后添加到项目,引入两个文件即可,不需要引入Jquery,此库自带: <link href="../js/layui- ...

  2. LVTTL与LVCMOS区别

    TTL电平的VIH/VIL一般是2V/0.8V,VOH/VOL一般是 2.4V/0.4V,不论是3.3V还是5V的TTL都一样的:CMOS的VIH/VIL一般是70%VCC/30%VCC,VOH/VO ...

  3. 配置apache使用https访问

    准备 yum install mod_ssl openssl 生成一个自签名证书 cd /etc/pki/CA 1.生成2048位的加密私钥 openssl genrsa -out server.ke ...

  4. 【干货】SIFT-Workstation 下载与安装 不跳过每一个细节部分

    SIFT-Workstation.ova     下载地址https://digital-forensics.sans.org/community/download-sift-kit       ov ...

  5. jdk1.8源码Thread与Runnable区别

    一.概念 Thread实现了Runnable接口 public class Thread implements Runnable { /* Make sure registerNatives is t ...

  6. 【源码阅读】Mimikatz相关资料

    Mimikatz GitHub (源码) https://github.com/gentilkiwi/mimikatz Mimikatz GitHub Wiki (包含了一些说明文档) https:/ ...

  7. Python_oldboy_自动化运维之路_线程,进程,协程(十一)

    本节内容: 线程 进程 协程 IO多路复用 自定义异步非阻塞的框架 线程和进程的介绍: 举个例子,拿甄嬛传举列线程和进程的关系: 总结:1.工作最小单元是线程,进程说白了就是提供资源的 2.一个应用程 ...

  8. PHP时间戳和日期转换

    获取当前时间 <?php var_dump(time()); //获取当前时间戳 int(1502245603) 时间戳转换为时间,可以用date(‘Y-m-s h:i:s’, 具体时间戳来实现 ...

  9. LeetCode(18):四数之和

    Medium! 题目描述: 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 t ...

  10. Kafka 集群配置SASL+ACL

    一.简介 在Kafka0.9版本之前,Kafka集群时没有安全机制的.Kafka Client应用可以通过连接Zookeeper地址,例如zk1:2181:zk2:2181,zk3:2181等.来获取 ...