Go语言中的内建函数new和make是两个用于内存分配的原语(allocation primitives)。对于初学者,这两者的区别也挺容易让人迷糊的。简单的说,new只分配内存,make用于slice,map,和channel的初始化。

1. new

这是一个用来分配内存的内建函数,但是与C++不一样的是,它并不初始化内存,只是将其置零。也就是说,new(T)会为T类型的新项目,分配被置零的存储,并且返回它的地址,一个类型为*T的值。在Go的术语中,其返回一个指向新分配的类型为T的指针,这个指针指向的内容的值为零(zero value)。注意并不是指针为零。

Go语言中的对象没有C++中的构造函数,如果用C来描述,Go中的new大概相当于:

T *t = (T*)malloc(sizeof(T))

memset(t, 0, sizeof(T))

其实,上面的描可能也不是很准确,也许用*t=zerovalue更准确。因为对于不同的数据类型,零值的意义是完全不一样的。比如,对于bool类型,零值为false;int的零值为0;string的零值是空字符串:

b := new(bool)

fmt.Println(*b)

i := new(int)

fmt.Println(*i)

s := new(string)

fmt.Println(*s)

输出:

false

0

注意最后有一个空字符串。

2. 初始化

很多时候,零值并不是一个好主意,我们需要做一些初始化。考虑如下结构体:

type Rect struct {

x, y float64

width, height float64

}

零值的Rect并没有多大用处,我们以下方式进行初始化:

rect3 := &Rect{0, 0, 100, 200}

rect4 := &Rect{width: 100, height: 200}

再申明一下,Go语言中没有C++中的构造函数,对象的创建一般交给一个全局的创建函数来完成:

func NewRect(x, y, width, height float64) *Rect {

return &Rect{x, y, width, height}

}

注意,这里与C/C++不同的是,返回一个局部变量的地址在Go语言中是绝对没有问题的;变量关联的存储在函数返回之后依然存在。

更直接的说,在Go语言中,如果一个局部变量在函数返回后仍然被使用,这个变量会从heap,而不是stack中分配内存。详细参考How do I know whether a variable is allocated on the heap or the stack?

3. make

内建函数make(T, args)与new(T)的用途不一样。它只用来创建slice,map和channel,并且返回一个初始化的(而不是置零),类型为T的值(而不是*T)。之所以有所不同,是因为这三个类型的背后引用了使用前必须初始化的数据结构。例如,slice是一个三元描述符,包含一个指向数据(在数组中)的指针,长度,以及容量,在这些项被初始化之前,slice都是nil的。对于slice,map和channel,make初始化这些内部数据结构,并准备好可用的值。

例如,

make([]int, 10, 100)

分配一个有100个int的数组,然后创建一个长度为10,容量为100的slice结构,该slice引用包含前10个元素的数组。对应的,new([]int)返回一个指向新分配的,被置零的slice结构体的指针,即指向值为nil的slice的指针。

var p *[]int = new([]int)       // allocates slice structure; *p == nil; rarely useful

var v  []int = make([]int, 100) // the slice v now refers to a new array of 100 ints

// Unnecessarily complex:这种做法实在是很蛋疼

var p *[]int = new([]int)

*p = make([]int, 100, 100)

// Idiomatic:习惯的做法

v := make([]int, 100)

记住make只用于map,slice和channel,并且不返回指针。要获得一个显式的指针,使用new进行分配,或者显式地使用一个变量的地址。

主要参考

《effective go》

作者:YY哥 
出处:http://www.cnblogs.com/hustcat/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

深入学习golang(4)—new与make的更多相关文章

  1. 学习Golang语言(6):类型--切片

    学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Gola ...

  2. 前端程序员学习 Golang gin 框架实战笔记之一开始玩 gin

    原文链接 我是一名五六年经验的前端程序员,现在准备学习一下 Golang 的后端框架 gin. 以下是我的学习实战经验,记录下来,供大家参考. https://github.com/gin-gonic ...

  3. 4 个技巧学习 Golang

    到达 Golang 大陆:一位资深开发者之旅. 2014 年夏天…… IBM:“我们需要你弄清楚这个 Docker.” 我:“没问题.” IBM:“那就开始吧.” 我:“好的.”(内心声音):”Doc ...

  4. 从别人的代码中学习golang系列--01

    自己最近在思考一个问题,如何让自己的代码质量逐渐提高,于是想到整理这个系列,通过阅读别人的代码,从别人的代码中学习,来逐渐提高自己的代码质量.本篇是这个系列的第一篇,我也不知道自己会写多少篇,但是希望 ...

  5. 从别人的代码中学习golang系列--02

    这篇博客还是整理从https://github.com/LyricTian/gin-admin 这个项目中学习的golang相关知识 作者在项目中使用了https://github.com/googl ...

  6. 从别人的代码中学习golang系列--03

    这篇博客还是整理从https://github.com/LyricTian/gin-admin 这个项目中学习的golang相关知识. 作者在项目中使用了 github.com/casbin/casb ...

  7. 深入学习golang(2)—channel

    Channel 1. 概述 “网络,并发”是Go语言的两大feature.Go语言号称“互联网的C语言”,与使用传统的C语言相比,写一个Server所使用的代码更少,也更简单.写一个Server除了网 ...

  8. 学习Golang的步骤建议

    一.快速入门 通过快速入门可以宏观的了解Go相关知识.快速入门可以去学习 go-tour 国内可以访问的中文版的 go-tour 地址有下面一些: http://gotour.qizhanming.c ...

  9. 初学者学习golang可能遇到的坑

    我也是个golang初学者,刚入门的话,有些"坑"还是不好发现的.如map只是定义了然后就拿来使用,变量的值覆盖等. 本来打算写一篇的,后面发现有人写的挺不错的,我就把里面的有些坑 ...

  10. 推荐一个学习golang的地址

    链接打开后,文字可以点击! http://yougg.github.io/static/gonote/GolangStudy.html#

随机推荐

  1. PoEdu - C++阶段班- Lesson02_C to C++

    1  原生bool类型 c++里面的bool类型才是真正原生的true和faul,比如常见的大写的"BOOL",它就不是原生的. 原生的与非原生的bool,它们的区别: 详细说下原 ...

  2. 【jQuery】: 定时刷新页面

    <%@page import="qflag.ucstar.seatmonitor.manager.SeatMonitorManager"%><%@ page la ...

  3. 关于checkbox与文字混排无法对齐的解决方法

    先前代码如下 <span style="vertical-align:middle"><input  type="checkbox" name ...

  4. Linux内核实现中断和中断处理(二)

    第一部分移步传送门召唤!!:http://www.cnblogs.com/lenomirei/p/5562086.html 上回说了Linux内核实现中断会把中断分为两部分进行处理,上回讲了上部分,这 ...

  5. hadoop 集群部署ganglia 监控服务与nagios 报警服务

      1. 部署ganglia 服务   ganglia 涉及到的组件:     数据监测节点(gmond):这个部件装在需要监测的节点上,用于收集本节点的运行情况,并将这些统计信息传送到gmetad, ...

  6. SQL调优之排名优化

    mysql> explain extended select t.rowno from (SELECT @rowno:=@rowno+1 as rowno,ur.customer_id as u ...

  7. 软件工程结组开发软件特色——NABC模型

    特点:通过学生提前点餐,可以让摊主在准备食材的时候有个参照,当准备的食材比较少的时候可以及时回家取来. N(Need):每当放学的时候,学校外边的卖饭摊位总是挤满了人,好多同学都要排好长的队等比较长的 ...

  8. 一个通用的makefile

    # ESDK the makefile setting file - chenwg@20131014 # you can modify "PC = 1" such as " ...

  9. synchronized同步锁+单利模式

    public static synchronized VolleyRequestController getInstance() {         if (sInstance == null) { ...

  10. 使用NHibernate(7)-- 一对一 && 一对多 && 多对多

    1, 一对一. 对于数据量比较大的时候,考虑查询的性能,肯能会把一个对象的属性分到两个表中存放:比如用户和用户资料,经常使用的一般是Id和用户名,用户资料(学校,籍贯等)是不经常被查询的,所以就会分成 ...