深入理解 Golang 中的 new 和 make 是什么, 差异在哪?

网友投稿 1093 2022-11-16

深入理解 Golang 中的 new 和 make 是什么, 差异在哪?

深入理解 Golang 中的 new 和 make 是什么, 差异在哪?

在 Go 语言中,有两个比较雷同的内置函数,分别是 ​​new​​​ 和 ​​make​​ 方法,其主要用途都是用于分配相应类型的内存空间。

看上去 ​​new​​​ 和 ​​make​​​ 都是分配内存的,那他们有什么区别呢?这个细节点也成为了不少 Go 语言工程师的面试题之一,值得大家一看。 在这篇文章中我们将来解答这个问题。

基本特性

make

在 Go 语言中,内置函数 ​​make​​​ 仅支持 ​​slice​​​、​​map​​​、​​channel​​ 三种数据类型的内存创建,其返回值是所创建类型的本身,而不是新的指针引用。

函数签名如下:

func make(t Type, size ...IntegerType)

具体使用示例

func main() { v1 := make([]int, 1, 5) v2 := make(map[int]bool, 5) v3 := make(chan int, 1) fmt.Println(v1, v2, v3)}

代码中,我们分别对三种类型调用了 ​​make​​ 函数进行了初始化。你会发现有的入参是有多个长度指定,有的没有。

这块的区别主要是长度(len) 和 容量(cap) 的指定,有的类型是没有容量这一说法,因此自然也就无法指定。

输出结果:

[0] map[] 0xc000044070

有一个细节点要注意,调用 ​​make​​ 函数去初始化 切片(slice) 的类型时,会带有零值,需要明确是否需要。 见过不少的小伙伴在这上面踩坑。

new

在 Go 语言中,内置函数 ​​new​​​ 可以对类型进行内存创建和初始化。其返回值是所创建类型的指针引用,与 ​​make​​ 函数在实质细节上存在区别。

函数签名如下:

func new(Type) *Type

具体使用示例:

type T struct { Name string}func main() { v := new(T) v.Name = "煎鱼"}

从上面的例子的效果来看,是不是似曾相似?其实与下面这种方式的一样的:

func main() { v := T{} v.Name = "煎鱼"}

输出结果均是:

&{Name:煎鱼}

其实 ​​new​​​ 函数在日常工程代码中是比较少见的,因为他可被替代。 一般会直接用快捷的 ​​​T{}​​ 来进行初始化,因为常规的结构体都会带有结构体的字面属性:

func NewT() *T { return &T{Name: "煎鱼"}}

这种初始化方式更方便。

区别在哪里

可能会有的小伙伴会疑惑一点,就是 ​​new​​​ 函数也能初始化 ​​make​​ 的三种类型:

v1 := new(chan bool)v2 := new(map[string]struct{})

那 ​​make​​​ 函数的区别,优势是什么呢? 本质上在于 make 函数在初始化时,会初始化 ​​​slice​​​、​​chan​​​、​​map​​​ 类型的内部数据结构,​​new​​​ 函数并不会。 例如:在 ​​​map​​​ 类型中,合理的长度(len)和容量(cap)可以提高效率和减少开销。 更进一步的区别:

​​make​​ 函数:

能够分配并初始化类型所需的内存空间和结构,返回引用类型的本身。具有使用范围的局限性,仅支持​​channel​​​、​​map​​​、​​slice​​ 三种类型。具有独特的优势,make 函数会对三种类型的内部数据结构(长度、容量等)赋值。

​​new​​ 函数:

能够分配类型所需的内存空间,返回指针引用(指向内存的指针)。可被替代,能够通过字面值快速初始化。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:详细聊聊Mybatis中万能的Map
下一篇:阿里开源Canal--简介
相关文章

 发表评论

暂时没有评论,来抢沙发吧~