New & make in go_Code
概述
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 语言不一样,栈区分配的存储空间不会随着函数的返回而释放,本地变量地址所占据的存储空间会生存下来。
New & make in go_Code的更多相关文章
- golang笔记——IDE
可选方案有 Lite IDE\GoSublime\Visual Studio Code\Goclipse\Vim 1.Lite IDE 这是国人开发的开源且跨平台的 golang 专属IDE,也算是目 ...
- Go 语言学习
golang中国 http://www.golangtc.com/ 第三方github学习 https://github.com/Unknwon/go-fundamental-programmingh ...
- C语言和go语言之间的交互
一.go代码中使用C代码 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import "C" 即可在go代码中使用C函数 代码示例: go代码:tes ...
- java中集合Collection转list对象
参考:java中集合Collection转list对象 首先我的需求是获取到购物车列表,购物车列表是一个Map对象,构造方法获取购物项,这里购物项是Collection对象 // 购物项集合,K商品I ...
- ubuntu下c/c++/python/go编译运行
C语言: .c文件 编译器gcc//my_code下hello.c文件 $sudo apt install gcc $gcc hello.c -o hello $./hello C++: .cpp文件 ...
- C语言和go语言之间的交互 - C语言中使用go语言,使用的go语言又使用了c语言
一.go语言中使用C语言 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import “C” 即可在go代码中使用C函数 代码示例: go代码:testC.go 1 pa ...
- (四十四)golang--协程(goroutine)和管道(channel)相结合实例
统计1-8000之间的素数. 整体框架: 说明:有五个协程,三个管道.其中一个协程用于写入数字到intChan管道中,另外四个用于取出intChan管道中的数字并判断是否是素数,然后将素数写入到pri ...
- golang数据结构之队列
队列可以用数组或链表实现,遵从先入先出. 目录结构: 在main中调用queue包中的属性和方法,如何调用参考另一篇文章: https://www.cnblogs.com/xiximayou/p/12 ...
- golang数据结构之循环链表
循环链表还是挺有难度的: 向链表中插入第一条数据的时候如何进行初始化. 删除循环链表中的数据时要考虑多种情况. 详情在代码中一一说明. 目录结构如下: circleLink.go package li ...
随机推荐
- python统计两个字符串从首字符开始最大连续相同的字符数
在python中统计两个字符串从首字符开始最大连续相同的字符数,函数如下: def get_num(s1, s2): num = 0 len_s1 = len(s1) list_s1 = [] for ...
- Httpd服务进阶知识-基于Apache Modele的LAMP架构之WordPress案例
Httpd服务进阶知识-基于Apache Modele的LAMP架构之WordPress案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装依赖包及数据库授权 博主推荐阅读 ...
- 数据结构中的堆(Heap)
堆排序总结 这是排序,不是查找!!!查找去找二叉排序树等. 满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树. 构建顶堆: a.构造初始堆 b.从最后一层非叶节点开始调整,一直到根节点 c.如果 ...
- Java 执行
java -cp****.jar ****.****.className [args] linux 下 -cp 参数使用 : 分割 一般都是 .:lib/* windows 下使用 ; 分割
- AHOI2014 奇怪的计算器 和 HDU5306 Gorgeous Sequence
线段树秀操作题. 奇怪的计算器 有 N 个数,一共会对这 N 个数执行 M 个指令(对没个数执行的指令都一样),每一条指令可以是以下四种指令之一:(这里 a 表示一个正整数) 加上 a 减去 a 乘以 ...
- wordpress角色权限汇总
我们在用wordpress开发的时候有时候需要设置不同的用户组及权限,具体有哪些角色权限呢?随ytkah一起来看看吧.WordPress使用了角色的概念,旨在让站点所有者能够控制用户在站点中可以做什么 ...
- Performance --- 前端性能监控
阅读目录 一:什么是Performance? 二:使用 performance.timing 来计算值 三:前端性能如何优化? 四:Performance中方法 五:使用performane编写小工具 ...
- MySQL binlog2sql实现MySQL误操作的恢复
对于MySQL数据库中的误操作删除数据的恢复问题,可以使用基于MySQL中binlog做到类似于闪回或者生成反向操作的SQL语句来实现,是MySQL中一个非常实用的功能.原理不难理解,基于MySQL的 ...
- 在调试时,有什么更好的方法可以监视最后一个win32错误?
我发现在代码中使用win32api时,需要多次监视最后一个win32错误!(在每次使用API后调用GetLastError()是不可行的解决方案!).. 在Visual Studio中,它们提供了一个 ...
- 套接字编程简介: IPV4套接字地址结构/ 通用套接字地址结构/ IPV6套接字地址结构/新通用套接字地址结构
IPv4套接字地址结构通常也称为“网际套接字地址结构”,它以sockaddr_in命名,定义在<netinet/in.h>头文件中. struct in_addr { in_addr_t ...