题目
new 和 make的区别是什么?
正文
在面试官问完我这个题目的时候,我真的是一脸懵逼!什么?new和make的区别?
这个问题在我看来和别人问我张三和李四的区别是什么是一样的?张三是张三啊,李四是李四啊,这个不是显而易见的区别吗?
各自有各自独立的作用的东西,为什么要说区别呢?难不成问到了我的知识盲区了!!!
当时的回答是new用来创建指针,而make一般用来创建map或者slice。
凑巧这两天看了一篇文章,一位大牛说了两者的区别,我就把文中讲到的两者的区别翻译到了下面。
区别
go 中有两个创建数据的函数:new和make。对于刚入门 go 语言的人来说这两个函数会让人困惑,但是他们会很快的自然而然的就可以区两者的区别了。基本的区别就是new(T)返回的是一个*T,这个指针指向了具体的数据(下图中的黑色指针)。但是make(T, args)会返回真实的T,而不是一个指针,通常T中通常包含一些指针(下图中的灰色指针)。new返回一个指针,指向的对象是其类型的零型,而make会返回一个复杂的结构体。
转折
真的就到此为止吗?直到我看到了stack_overflow的一些回答,我才恍然大悟。其中有一条的回答是我最为满意的,但是赞并不是最高的,我选择把这个答案翻译到下面
函数make会对对象(仅仅包括slice、map、chan三种)进行分配内存并初始化。和new相似,make函数的第一个参数是一个类型,但是它也可以接受表示数量的第二个参数。和new不同的地方是make返回的是创建的对象,而不是对象的指针。并且make分配的值是初始化好了的(new中是设置为对应类型的零值)。之所以这么做的原因是 slice, map 和 chan 是数据结构,它们需要初始化,否则就不可使用。正是这个原因使得new和make不同。
下面的来自于 Effective Go 中的代码会使这个问题更加清晰
p *[]int = new([]int) // *p = nil, which makes p useless
v []int = make([]int, 100) // creates v structure that has pointer to an array, length field, and capacity field. So, v is immediately usable
总结
虽然 Stack Overflow 上的回答给我解释了两者的区别,但是更让我信服的是告诉了我make的作用。最后,我还是想说,这两者的区别是显而易见的,这个问题还是让人无语!还不如直接问make的作用,或者为什么需要make。