Go语言中new和 make的区别详解

Python016

Go语言中new和 make的区别详解,第1张

1、new 的主要特性

首先 new 是内建函数,定义也很简单:

func new(Type) *Type

内建函数 new 用来分配内存,第一个参数是一个类型,不是一个值,返回值是一个指向新分配类型零值的指针

实现一个类似 new 的功能:

func newInt() *int {

var i int

return &i

}

someInt := newInt()

函数的功能跟 someInt := new(int) 一模一样。定义 new 开头的函数时,出于约定也应该返回类型的指针。

2、make 的主要特性

make 也是内建函数,定义比 new 多了一个参数,返回值也不同:

func make(Type, size IntegerType) Type

内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型,具体说明如下:

Slice: 第二个参数 size 指定了长度,容量和长度相同。

可以传入第三个参数来指定不同的容量值,但必须不能比长度值小。

比如 make([]int, 0, 10)

Map: 根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存

Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者忽略容量,管道没有缓冲区。

3、总结

new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

英语中make一词用法甚多,是使用频率最高的动词之一,而make作使役动词的用法也很常见。意思是“使成为”、“使作为”、“使变成”, 其后的复合宾语(即宾语+宾语补足语)有以下表达方式:\x0d\x0a1. make +宾语+名词(作宾语补足语)\x0d\x0aMost pop singers make music their career.\x0d\x0a大多数流行歌手把音乐当作他们的职业。\x0d\x0aBill Gates’ Microsoft makes him a phenomenon in the business world.\x0d\x0a比尔·盖茨的微软使他成为商界的一个奇才。\x0d\x0aWhat makes the ocean such a great place to live?\x0d\x0a究竟是什么东西使大海成为如此优越的生活场所呢?\x0d\x0aEuropean football is played in 80 countries, making it the most popular sport in the world.\x0d\x0a80个国家踢欧式足球,使它成为世界上最受欢迎的运动。\x0d\x0aAfter all, what makes a new invention such a wonderful thing is that it allows us to do something we could not do before.\x0d\x0a毕竟, 一项发明之所以成为如此奇妙的事情就在于它可以让我们做以前不能做的事。\x0d\x0a2. make +宾语+不带to的不定式(作宾语语补足语)\x0d\x0aNobody made us go to bed at a certain time.\x0d\x0a没有人让我们在某一固定时间就寝。\x0d\x0aPop music makes people feel easy and forget about the real world; rock music makes people think about the world and how to make their life better.\x0d\x0a流行音乐令人松弛安心, 忘记这真实的世界, 而摇滚乐使人思考这个世界和如何改善自己的生活。\x0d\x0aNothing can make me turn against my country.\x0d\x0a什么也不能使我背叛我的祖国。\x0d\x0aLove may create the wonder, and may make people become satisfied and optimistic.\x0d\x0a爱可以创造奇迹, 可以让人变得满足和乐观。\x0d\x0a但改成被动语态时, 则要加to。\x0d\x0aChildren should be made to understand the importance of saving water.\x0d\x0a应该让孩子们理解节水的重要性。\x0d\x0a3. make +宾语+形容词(作宾语补足语)\x0d\x0aBut I was happy to help because I knew it was to realize our dream of making black and white people equal.\x0d\x0a但是我乐于帮忙, 因为我知道, 这是为了实现我们黑人和白人平等的梦想。\x0d\x0aThe purpose of new technologies is to make life easier, not to make it more difficult.\x0d\x0a新技术的目的是使生活变得更加容易, 而不是变得更加困难。\x0d\x0aInternet makes our lives easy and convenient.\x0d\x0a互联网使我们的生活变得容易和方便。\x0d\x0aThe chemical structure of water also makes it different from almost every-thing else on earth.\x0d\x0a化学结构还使水不同于世界上几乎所有的其他物质。\x0d\x0aUnfortunately, this function also makes estuaries very sensitive to enviro-mental pollution.\x0d\x0a不幸的是, 这个作用也使河口对环境污染很敏感。\x0d\x0aHarry learns the truth about his past, a dark secret that will make his life and choices more difficult.\x0d\x0a哈利了解了自己的真实身世, 隐藏其中的秘密使他的生活和选择面临更大的困难。\x0d\x0a4. make +宾语+过去分词(作宾语补足语)\x0d\x0aThe teacher raised his voice so that he could make himself heard.\x0d\x0a那个老师提高了嗓门以便别人能听到他。\x0d\x0aCan you easily make yourself understood in English?\x0d\x0a你能用英语轻易地表达你的思想吗?\x0d\x0aHis actions made him universally respected.\x0d\x0a他的行为使他处处受到尊敬。\x0d\x0a5. make +宾语+介词短语(作宾语补足语)\x0d\x0aYou made him into an honest one.\x0d\x0a你使他成为一个诚实的人。\x0d\x0a“Make yourself at home,” the hostess said to me as soon as I entered the house.\x0d\x0a我刚一进门, 女主人就对我说:“别客气, 就像在你自己家一样。”\x0d\x0a6. make +宾语+从句(作宾语补足语)\x0d\x0aWhat has made China what she is today?\x0d\x0a是什么让中国变成今天的样子?\x0d\x0aWe will soon make our school what your school is now.\x0d\x0a我们不久就要把我们的学校发展成你们学校目前的那个样子。\x0d\x0a7. make +形式宾语it +形容词或名词(做宾语补足语) +带to的不定式作真正的宾语\x0d\x0aThis makesit possible for agriculture and industry to develop quickly.\x0d\x0a这使工农业有可能很快发展。\x0d\x0aPeople in the West make it a rule to buy Christmas presents for their rela-tives and friends.\x0d\x0a西方国家的人常在圣诞节时购买礼物给亲属和朋友。\x0d\x0aPedestrians, both old and young, should make it a habit to use overhead bridges.\x0d\x0a行人, 不论老幼, 都该养成走人行天桥的习惯。\x0d\x0a8. make +形式宾语it +形容词或名词(作宾语补足语) +从句(作真正的宾语)\x0d\x0aThey want to make it clear to the public that they do an important and necessary job.\x0d\x0a他们要向公众表明, 他们所做的工作不但重要, 而且是必不可少的。

队列的概念在 顺序队列 中,而使用循环队列的目的主要是规避假溢出造成的空间浪费,在使用循环队列处理假溢出时,主要有三种解决方案

本文提供后两种解决方案。

顺序队和循环队列是一种特殊的线性表,与顺序栈类似,都是使用一组地址连续的存储单元依次存放自队头到队尾的数据元素,同时附设队头(front)和队尾(rear)两个指针,但我们要明白一点,这个指针并不是指针变量,而是用来表示数组当中元素下标的位置。

本文使用切片来完成的循环队列,由于一开始使用三个参数的make关键字创建切片,在输出的结果中不包含nil值(看起来很舒服),而且在验证的过程中发现使用append()函数时切片内置的cap会发生变化,在消除了种种障碍后得到了一个四不像的循环队列,即设置的指针是顺序队列的指针,但实际上进行的操作是顺序队列的操作。最后是对make()函数和append()函数的一些使用体验和小结,队列的应用放在链队好了。

官方描述(片段)

即切片是一个抽象层,底层是对数组的引用。

当我们使用

构建出来的切片的每个位置的值都被赋为interface类型的初始值nil,但是nil值也是有大小的。

而使用

来进行初始化时,虽然生成的切片中不包含nil值,但是无法通过设置的指针变量来完成入队和出队的操作,只能使用append()函数来进行操作

在go语言中,切片是一片连续的内存空间加上长度与容量的标识,比数组更为常用。使用 append 关键字向切片中追加元素也是常见的切片操作

正是基于此,在使用go语言完成循环队列时,首先想到的就是使用make(type, len, cap)关键字方式完成切片初始化,然后使用append()函数来操作该切片,但这一方式出现了很多问题。在使用append()函数时,切片的cap可能会发生变化,用不好就会发生扩容或收缩。最终造成的结果是一个四不像的结果,入队和出队操作变得与指针变量无关,失去了作为循环队列的意义,用在顺序队列还算合适。

参考博客:

Go语言中的Nil

Golang之nil

Go 语言设计与实现