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}

}

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》

 

 

 

最新文章

  1. python的一道面试题 __call__ 的使用.
  2. AtCoder Grand Contest 6
  3. Python 之 for循环中的lambda
  4. java 基础加强--书籍+题目+上机测试
  5. 移动端图片滚动加载-lazyload实现的要点总结
  6. 【BZOJ-2095】Bridge 最大流 + 混合图欧拉回路 + 二分
  7. Android之旅---广播(BroadCast)
  8. VC++2010 中Debug和Release配置
  9. C# string格式的日期时间字符串转为DateTime类型
  10. Hadoop1.x与2.x安装笔记
  11. (step6.3.4)hdu 1151(Air Raid——最小路径覆盖)
  12. Algorithm
  13. sql防注入代码
  14. Linux解压缩总结
  15. Spring MVC处理(下周完善)
  16. android:单位和尺寸
  17. struts配置result类型为json后导致页面不能访问的错误
  18. 腾讯Bugly2015年移动应用质量大数据报告 原 荐
  19. (笔记)Linux下的解压、压缩命令集合
  20. XML文件解析-SaxReader

热门文章

  1. 搭建nginx环境
  2. Django 之form简单应用
  3. idea控制台乱码修改
  4. Vue移动端焦点状态跳转页面,焦点和键盘不消失的问题
  5. 【SpringBoot】自动配置
  6. Cacti-0.8.8b详细安装及配置步骤
  7. Vue介绍:vue导读2
  8. .NET SignalR中长连接与HUB连接的使用方式以及区别
  9. mongo批量写入es
  10. Spring源码解读(一)