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. Xcode升级更新后,恢复cocoapods以及插件的方法

    今天将手机系统更新到iOS9.3了,在Xcode7.1上做真机调试,提示找不到适合的SDK,才知道必须要升级Xcode才行,于是升级Xcode到7.3. 升级之后遇到很多麻烦,cocoapods没有了 ...

  2. Oracle一个中文汉字占用几个字节

    Oracle 一个中文汉字 占用几个字节,要根据Oracle中字符集编码决定   查看oracle server端字符集 select userenv('language') from dual; 如 ...

  3. opengles2.0 学习笔记

    - 指定图元顶点数据(亦称顶点属性) 顶点属性有常量顶点属性,和属性数组. 常量指的是所有的顶点都公用此属性.比如单色的三角形,则颜色属性对所有的顶点都一样. 通过命令glVertexAtrrib*f ...

  4. struts2中的constant配置详解

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-/ ...

  5. 现在的SQLSERVER数据库监控软件有哪些?

    现在的SQLSERVER数据库监控软件有哪些? 收集了一下当前SQLSERVER数据库监控软件,发现开源免费的真的是“没有” Questsoftware  Quest's spotlight(收费)  ...

  6. 用c#开发微信 (11) 微统计 - 阅读分享统计系统 1 基础架构搭建

    微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享 ...

  7. Nginx运行Mono Web (ASP.NET)

    Mono Web除了可以使用Apache/mod_mono方式承载运行外,还可以使用Nginx/FastCGI方式运行. Nginx配置asp.net更简单方便,用处也多,可以通过FastCGI运行a ...

  8. Nginx学习笔记(四) 源码分析&socket/UDP/shmem

    源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_socket.h&Ngx_s ...

  9. [安卓] 8、VIEW和SURFACEVIEW游戏框架

    这是个简单的游戏框架,上图显示我们实现了屏幕上对象的位置控制.这里要1个简单的layout资源和2个java类:在MainActivity中主要和以往一样,唯一不同的是去除电池图标和标题等操作,然后第 ...

  10. [WinAPI] 串口读写

    #include <stdio.h> #include <stdlib.h> #include <windows.h> HANDLE hComm; OVERLAPP ...