c语言编程笔录

首页 >   > 笔记大全

笔记大全

Go语言中make和new有什么区别

更新时间:2023-11-28

介绍

在Go语言中,能够动态创建新对象的方式有两种,一种是使用`new`关键字,另一种是使用`make`函数。尽管这两种方式都可以用于在内存中分配新对象,但它们的表现方式略有不同,因为它们为不同的数据类型服务。这篇文章将会讨论这两种实现,分别指出它们的区别和使用场景。

new

`new`是一个内置函数,在Go语言中它用于创建一个指向类型零值的指针。这个零值的内存被设置为0。因此,当在内存中创建一个新的对象时,这个对象的值被初始化为相应类型的零值。对于指针,零值表示指向nil,并且该指针还没有指向任何有效的内存位置。 下面是一些使用`new`关键字的示例:
a := new(int) //分配int类型的零值内存,a是指向int类型零值的指针
b := new(string) //分配string类型的零值内存,b是指向string类型零值的指针

make

作为一个专门用于slice,map和channel创建的内置函数,`make`有许多特殊的显式和隐式规则,因此使用起来需要特别关注。 下面是关于使用`make`创建slice、map和channel的示例:
slice
使用`make`函数创建一个空的slice,分配的内存符合slice的先前定义。当使用`make`创建slice时,必须指定slice的容量。 下面是一个用于使用`make`初始化slice的示例:
a := make([]int, 5) //创建一个拥有5个元素的int类型slice,值全为0
a[0] = 1 // 将下标为0的元素赋值为1
map
使用`make`函数创建一个新的空map。当使用`make`创建map时,必须指定map的存储方式(map中的键和值可以是任何类型,有关map中键的详细信息,请参阅map类型) 下面是使用`make`初始化map的示例:
var b map[string]int
b = make(map[string]int)
channel
使用`make`函数创建一个新的channel,分配了正常的内存并初始化了其他必要的内部结构体。 下面是使用`make`初始化channel的示例:
a := make(chan int) //创建一个int类型的channel
go func(){
    a <- 42 //将42写入channel a中
}()
fmt.Println(<-a) //等待读取channel a中的值,并打印

总结

虽然`new`和`make`都能够在内存中分配空间,并创建新对象,但它们的语义和表现稍有不同。但总结起来,`new`用于分配零值对应类型的内存,并返回该值的指针,而`make`则用于创建内置类型slice、map和channel。但需要注意,由于`make`要为底层的具体类型分配内存,所以它只能用于被初始化为初始值的类型上。