golang new和make的区别

发布时间:2024-07-02 22:16:12

在golang中,我们经常使用new和make来创建变量。虽然它们都能用于初始化数据,但它们的实现方式和用途却有所不同。

new和make的基本区别

首先,我们来讨论一下new和make的基本区别。

new是一个内建函数,它的作用是为指定的类型分配一片内存空间,并返回该类型的指针。简单来说,new只是做了一件事情,即分配内存。例如:

var p *int
p = new(int)

上述代码中,我们为int类型的变量p分配了一片内存空间,并把该内存空间的地址赋值给了变量p。

而make也是一个内建函数,它的作用是创建一个指定类型的对象,并返回该对象。简而言之,make做了两件事情:分配内存和初始化对象。我们可以这样使用make:

s := make([]int, 0, 10)
m := make(map[string]int)

上述代码中,我们分别使用make创建了一个int类型的切片和一个string到int的映射。

new和make的适用场景

接下来,我们讨论一下new和make的适用场景。

new通常用于创建一个具体类型的指针,例如指针、数组、结构体等。我们来看一个示例:

type Person struct {
    name string
}

func main() {
    p := new(Person)
}

上述代码中,new用于创建了一个名为Person的结构体的指针p。由于new只会分配内存而不会进行初始化,p的字段name将被自动赋值为空字符串。

相比之下,make通常用于创建slice、map和channel类型,因为它们都是对应的引用类型。我们来看一个示例:

s := make([]int, 0, 10)
m := make(map[string]int)
c := make(chan int)

上述代码中,make分别创建了一个int类型的切片s、一个string到int的映射m和一个int类型的channel c。由于make会分配内存并进行初始化,我们可以直接使用它返回的对象,而不需要手动初始化。

new和make的底层实现

最后,我们讨论一下new和make的底层实现。

new的底层实现其实很简单,它调用了runtime.new函数:

func new(Type) *Type {
    var p unsafe.Pointer
    return (*Type)(p)
}

可以看出,new只是声明了一个变量p,并将其转换成了对应类型的指针返回。

而make的底层实现稍微复杂一些,它的底层实现取决于具体的类型。以创建slice的make为例:

func make([]T, len, cap) []T {
    // ... 省略其他代码
    return tmp
}

可以看到,make函数在底层调用了runtime.makeslice函数,并将其返回。

总结

综上所述,new和make都能用于初始化数据,但它们的实现方式和用途有所不同。new只是分配内存,适用于创建指针、数组、结构体等类型的对象;而make不仅分配内存,还会进行初始化,适用于创建slice、map和channel等引用类型的对象。在选择使用new还是make时,我们需要根据具体的类型和需求来决定。

相关推荐