Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > go new和make区别及new返回是指针

go new和make的区别以及为什么new返回的是指针问题分析

作者:胡萝卜的兔

Go语言中new和make的区别在于:new用于分配值类型内存并返回指针,适用于所有值类型;make用于创建并初始化slice、map和channel,只适用于引用类型,new返回指针可以明确表示值是在堆上分配的,避免不必要的值拷贝,并且与零值初始化语义一致

Go 语言中 new 和 make 的区别

在 Go 语言中,new 和 make 都是用于内存分配的内建函数,但它们有不同的用途和行为。

new 函数

new(T) 用于为值类型分配内存并返回指针:

p := new(int)   // p 是 *int 类型,指向一个零值的 int
fmt.Println(*p) // 输出 0

type Person struct {
    Name string
    Age  int
}

personPtr := new(Person) // 分配 Person 结构体的零值并返回指针

make 函数

make 专门用于创建 slice、map 和 channel 这三种引用类型:

s := make([]int, 10)     // 长度为10的切片
m := make(map[string]int) // 初始化一个map
c := make(chan int, 5)   // 缓冲大小为5的通道

主要区别

当需要初始化 slice、map 或 channel 时使用 make

对于结构体,通常使用 &T{} 语法比 new 更常用

// 通常这样创建结构体实例
p := &Person{Name: "Alice", Age: 30}

// 而不是
p := new(Person)
p.Name = "Alice"
p.Age = 30

new 为什么要返回指针呢

1. 明确表示分配在堆上

返回指针可以明确表示这个值是在堆上分配的,而不是栈上。在 Go 中:

2. 避免不必要的值拷贝

如果 new 返回值而不是指针:

v := new(MyStruct) // 假设 new 返回值
funcThatTakesPointer(&v) // 需要显式取地址

这样会导致额外的值拷贝。而返回指针可以直接传递,更高效。

3. 与零值初始化语义一致

new 的语义是"分配并返回零值",如果返回值:

v := new(int) // 假设返回 0

那么就无法区分这是新分配的值还是字面量 0。返回指针 *int 则明确表示了这是一个新分配的值。

4. 与 make 区分明确

Go 语言设计者刻意区分:

5. 实际使用场景的需要

大多数需要 new 的场景都是需要指针的场景:

// 常见用法
var p *TreeNode
p = new(TreeNode)

// 如果 new 返回值,就需要写成
var p TreeNode
pp := &p
// 这样反而更不直观

返回值的设计问题

如果 new 返回值:

因此,返回指针是更合理的设计选择,它:

在 Go 中,如果你不需要指针,完全可以直接声明值类型变量或使用结构体字面量 T{},而不需要使用 new。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文