Go语言中new()和make()的区别

Kevin501 等级 295 0 0

1. Go语言中的值类型和引用类型

  • 值类型:int,float,bool,string,struct数组 (数组要特别注意,别搞混了)

变量直接存储值,分配栈区的内存空间,这些变量所占据的空间在函数被调用完后会自动释放。

  • 引用类型:slice,map,chan和值类型对应的指针

变量存储的是一个地址(或者理解为指针),指针指向内存中真正存储数据的首地址。内存通常在堆上分配,通过GC回收。

2. new() vs make()

对值类型和引用类型了解之后,再来理解new()和make()就不难了,其实只要有C/C++背景的理解起来都不难。比如我们声明一个int类型的数据,一般是这样的:

var i int

var s string

当我们不指定变量的默认值时,这些变量的默认值就是对应的零值。(int类型的零值是0,string类型的零值是"",引用类型的零值是nil)。我们可以直接对值类型的变量进行赋值,修改变量对应的值等等。但是,如果声明的变量是引用类型呢?这就需要用到new()或make()函数了。先来看这样一个例子:

var i int // 值类型
i = 10 fmt.Println(i) // 10

var p \*int // 引用类型
\*p = 10 fmt.Println(\*p) //panic: runtime error: invalid memory address or nil pointer dereference

从例子可以看到,当对指针p进行赋值的时候,出现了panic,提示p 是无效的内存地址或是空指针引用。也就是说,对于引用类型的变量,我们不仅要声明变量(这仅仅是给变量取个名字),更重要的是,我们得手动为它分配空间!好在Go中还有GC,如果是C/C++,对于指针类型,除了手动申请空间,更要手动释放空间。

new()方法就是为 int/bool/struct等 值类型分配内存空间,返回相应类型的指针;而make()就是专为slice,map,channel分配空间。

new()

该方法的参数要求传入一个类型,而不是一个值,它会申请一个该类型大小的内存空间,并会初始化为对应的零值,返回指向该内存空间的一个指针。如下:

// The new built-in function allocates memory. The first argument is a type, // not a value, and the value returned is a pointer to a newly // allocated zero value of that type.
func new(Type) \*Type

因此,我们可以稍稍修改上面错误的程序.

var p \*int // 引用类型,或者写成 p := new(int)
p = new(int) \*p = 10 fmt.Println(\*p) // 10 

make()

make也是用于内存分配,但是和new不同,它只用于slice、map和channel的内存创建,它返回的类型就是类型本身,而不是它们的指针类型。

// The make built-in function allocates and initializes an object of type // **slice, map, or chan (only)**. Like new, the first argument is a type, not a // value. Unlike new, make's return type is the same as the type of its // argument, not a pointer to it. The specification of the result depends on // the type: // Slice: The size specifies the length. The capacity of the slice is // equal to its length. A second integer argument may be provided to // specify a different capacity; it must be no smaller than the // length. For example, make(\[\]int, 0, 10) allocates an underlying array // of size 10 and returns a slice of length 0 and capacity 10 that is // backed by this underlying array. // Map: An empty map is allocated with enough space to hold the // specified number of elements. The size may be omitted, in which case // a small starting size is allocated. // Channel: The channel's buffer is initialized with the specified // buffer capacity. If zero, or the size is omitted, the channel is // unbuffered.
func make(t Type, size ...IntegerType) Type
收藏
评论区

相关推荐

Golang指南:顶级Golang框架、IDE和工具列表
自推出以来,Google的Go编程语言(Golang)越来越受主流用户的欢迎。在2016年12月的一份调研中,3,595名受访者中有89%表明他们在工作中或工作以外用Go语言编程。 此外,在编程语言中,Go语言在专业知识和偏好方面排名最高。2017年7月,在Tiobe的年度编程语言排名(https://www.tiobe.com/tiobeindex
【Golang】Go入门及进阶书籍推荐
Go入门教程全集 链接: https://pan.baidu.com/s/1mWD7DpRa56WXi7WmNaohOg(https://pan.baidu.com/s/1mWD7DpRa56WXi7WmNaohOg) 提取码: ki1e Cloud.Native.Go.pdf C和指针.pdf C面向对象多线程编程.pdf Design Patt
【Golang】Go 语言今年 12 岁,何去何从,现状到底如何?
不说不知道,一说下一跳。Go 语言已经开源 11 周年了,感觉是一路高歌, Release History (polarisxu 整理)如下: 2011 年 3 月 16 日,Go 语言的第一个稳定版本 r56 发布; 2012 年 3 月 28 日,Go 语言的第一个正式版本 Go1 发布,并承诺 1.x 的 兼容性; 2013 年 5 月 13
【程序人生】毕业入职后,C++转Go语言工作半年感受
我在大学期间就听说了Go并学习了一段时间,坦白的说,那时候对Go是比较无感的,因为并 没有看到Go特别亮眼的地方,可能和我使用C、C、Java有关,这三
[Go] GO语言中的md5和sha256加密
项目中经常使用的md5和sha256加密函数 //md5加密 func Md5(src string) string { m : md5.New() m.Write(byte(src)) res : hex.EncodeToString(m.Sum(nil)) return res } //Sha256加密
Go语言中new()和make()的区别
1. Go语言中的值类型和引用类型 值类型:int,float,bool,string,struct和数组 (数组要特别注意,别搞混了) 变量直接存储值,分配栈区的内存空间,这些变量所占据的空间在函数被调用完后会自动释放。 引用类型:slice,map,chan和值类型对应的指针 变量存储的是一个地址(或者理解为指针),指针指向内存中真
go语言中,数组与切片的区别?
切片是Go 语言核心的数据结构,然而刚接触 Go 的程序员经常在切片的工作方式和行为表现上被绊倒。比如,明明说切片是引用类型但在函数内对其做的更改有时候却保留不下来,有时候却可以。究其原因是因为我们很多人用其他语言的思维来尝试猜测 Go 语言中切片的行为,切片这个内置类型在 Go 语言底层有其单独的类型定义,而不是我们通常理解的其他语言中数组的概念。 文章
Go语言开发的利与弊
Go 语言有多火爆?国外如 Google、AWS、Cloudflare、CoreOS 等,国内如七牛、阿里等都已经开始大规模使用 Go 语言开发其云计算相关产品。在 Go 语言的使用过程中,需要注意哪些 Yes 和 But? 最近,我们使用 Go 语言编写了一个 API,Go 语言是一种开源编程语言,2009 年由 Google 推出。在使用 Go 进行开
知乎从Python转为Go,是不是代表Go比Python好?
众所周知,知乎早在几年前就将推荐系统从 Python 转为了 Go。于是乎,一部分人就说 Go 比 Python 好,Go 和 Python 两大社区的相关开发人员为此也争论过不少,似乎,谁也没完全说服谁。 知乎从Python转为Go,是不是代表Go比Python好?我认为,各有优点,谁也取代不了谁,会长期共存! “由 Python 语言转向 Go 语言
go的三个运行基本命令的区别,go run ,go build 和 go install
最近在自学go,遇到点基础的问题,通过自己实际操作之后得出结论在实际操作之前,我们需要知道go有三种源码文件:      1,命令源码文件;声明自己属于main包,并且包含main函数的文件,每个项目只能有一个这样的文件,即程序的入口文件      2,库源码文件;不能直接被执行的源码文件      3,测试源码文件本次操作不涉及测试源码文件。go run
go语言开发入门:GO 开发者对 GO 初学者的建议
以促进 India 的 go 编程作为 GopherConIndia 承诺的一部分。我们采访了 40 位 Gophers(一个 Gopher 代表一个 GO 项目或是任何地方的 GO 程序员),得到了他们关于 GO 的意见。如果你正好刚刚开始 go 编程,他们对于我们一些问题的答案可能会对你有非常有用。看看这些。应该做:通读 the Go standard
[concurrent-map]-并发map在go中的使用
关于我 通过学习和分享的过程,将自己工作中的问题和技术总结输出,希望菜鸟和老鸟都能通过自己的文章收获新的知识,并付诸实施。 引言Go语言原生的map类型并不支持并发读写。在Go 1.9之前,go语言标准库中并没有实现并发map。在Go 1.9中,引入了sync.Map。 concurrentmap的优势concurrentm
一篇文章彻底弄懂理解和高效运用切片(slice)
slice,中文多译为“切片”,是 Go 语言在数组之上提供的一个重要的抽象数据类型。在 Go 语言中,绝大多数需要使用数组的场合,切片都实现了完美替代。并且和数组相比,切片提供了更通用、功能更强大且便捷的数据序列访问接口。 1. 切片究竟是什么在对切片一探究竟之前,我们先来简略了解一下 Go 语言中的数组。Go 语言数组是一个固定长度的、容纳同构类型元素的
一篇文章彻底弄懂go语言方法的本质
Go 语言不支持经典的面向对象语法元素,比如:类、对象、继承等。但 Go 语言也有方法(method)。和函数相比,Go 语言中的方法在声明形式上仅仅多了一个参数,Go 称之为 receiver 参数。而 receiver 参数正是方法与类型之间的纽带。Go 方法的一般声明形式如下:gofunc (receiver T/T) MethodName(参数列表)
go语言定义“零值可用”的类型
1. Go 类型的零值作为 C 程序员出身的我,我总是喜欢用在使用 C 语言的”受过的苦“与 Go 语言中得到的”甜头“做比较,从而来证明 Go 语言设计者在当初设计 Go 语言时是做了充分考量的。在 C99 规范中,有一段是否对栈上局部变量进行自动清零初始化的描述: 如果未显式初始化且具有自动存储持续时间的对象,则其值是不确定的。规范的用语总是晦涩难懂的。