new and make

new and make

在 Go 语言中, newmake 方法,其主要用途都是用于分配相应类型的内存空间。简单的说,new只分配内存,make用于slice,map,和channel的初始化。

方法签名

func make(t Type, size …IntegerType) Type

func new(Type) *Type

make

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

slice map channel 本身就是引用类型

1
2
3
4
5
6
7
8
9
func main() {
v1 := make([]int, 1, 5)
v2 := make(map[int]bool, 5)
v3 := make(chan int, 1)

fmt.Println(v1, v2, v3)
}

// [0] map[] 0xc000044070

调用 make 函数去初始化切片(slice)的类型时,会带有零值

new

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type T struct {
Name string
}

func main() {
// 以下两种实现方式一样
// 其实 new 函数在日常工程代码中是比较少见的,因为他可被替代。
v := new(T)
v.Name = "煎鱼"

vv := &T{}
vv.Name = "煎鱼"
fmt.Println(v, vv) //&{煎鱼} &{煎鱼}
}

区别

new 返回指针,make 返回引用类型

new 没有参数,make 需要指定类型

make 返回初始化后可以直接使用的对象,new 返回还需要初始化的指针

make 只用于 slice、map、channel 等内置引用类型,new 可用于任意类型

综合上面的分析,使用 new 和 make 的一些原则:

  • new 用于值类型和用户定义的类型,如数组、结构体
  • make 用于内置引用类型,如切片、map、channel

一个简单的区分记忆法则是:

  • new 给类型本身分配内存
  • make 从类型生成对象

日常使用中,对内置引用类型要优先考虑使用 make 进行初始化。

new()make() 的底层实现原理

new() 的底层实现原理

  • new() 函数在底层使用了 Go 的 runtime.newobject 函数。
  • runtime.newobject 函数会分配一块内存,大小为指定类型的大小,并将该内存清零。
  • 然后,runtime.newobject 函数会返回这块内存的指针。

make() 的底层实现原理

  • make() 函数在底层使用了 Go 的 runtime.makesliceruntime.makemapruntime.makechan 函数。
  • runtime.makeslice 函数用于创建切片,它会分配一块连续的内存空间,并返回切片结构体。
  • runtime.makemap 函数用于创建映射,它会分配一块哈希表内存,并返回映射结构体。
  • runtime.makechan 函数用于创建通道,它会分配一块通道内存,并返回通道结构体。

参考连接

Go : new 和 make 是什么,差异在哪?大家好,我是煎鱼。 在 Go 语言中,有两个比较雷同的内置函数,分别是 - 掘金

golang new和make的区别 - golang开发笔记 - SegmentFault 思否

理解 Go make 和 new 的区别 | 三月沙