在Go语言的世界里,有两个非常贴心的助手,

它们可以帮助我们创建和准备各种各样的数据结构,

这两个助手的名字叫做 make 和 new。

虽然它们都是用来帮助我们分配内存的,但是它们各自擅长的事情却有所不同。

首先,让我们来认识一下 new。

new 是一个非常简单的家伙,它只做一件事情:

为我们想要的数据类型分配一块全新的内存空间,并且返回一个指向这片空间的指针。

这个指针指向的地方,会自动填充该类型的默认值,也就是零值。

想象一下,new 就像一个忠实的管家,你告诉他你需要一个特定类型的新房间,他就会为你准备好,并把钥匙(指针)交给你。

举个例子,假设我们有一个表示学生的结构体 Student,我们想要为它创建一个新的实例,就可以请 new 出马了:

type Student struct {
name string
age int
}

var s *Student
s = new(Student) // new帮我们分配了内存,并返回了指向这片内存的指针
s.name = "小明" // 我们给这个学生起了个名字叫小明

fmt.Println(s)

如果我们忘记使用 new,那么程序在运行时就会遇到麻烦,因为它不知道要把数据放在哪里,就像是试图进入一个不存在的房间一样。

接下来,我们再来聊聊 make。

make 是一个更专业的助手,它专注于创建和初始化 Go 语言中的三种特殊数据结构:切片(slice)、映射(map)和通道(channel)。

make 的工作不仅仅是分配内存,它还会确保这些数据结构被正确地初始化,这样我们就可以直接使用了。

和 new 不同,make 返回的不是指针,而是这些数据结构本身,因为它们本身就是引用类型,就像是一扇已经打开的门,我们直接走进去就好了。

例如,我们想要创建一个装有三个字符串的切片,就可以这样使用 make:

// 使用make创建一个字符串切片,并告诉它我们想要三个位置
mySlice := make([]string, 3)
mySlice[0] = "语文" // 我们可以立刻开始使用这个切片
mySlice[1] = "数学"
mySlice[2] = "英语"

fmt.Println(mySlice)

简单来说,new 和 make 都是帮助我们创建数据结构的助手,但是它们各有专长。

new 更适合于创建基本类型的数据,并返回一个指向这些数据的指针;

而 make 则是 slice、map 和 channel 的好朋友,它不仅分配内存,还负责初始化,让我们可以直接使用这些数据结构。