Go语言中new()与make()的核心区别及适用场景

Noah
Noah
发布时间:2026-10-14 | 3人浏览过
原创

Go语言的new()和make()常被初学者混用,但二者在设计初衷与适用范围上截然不同。new()是通用内存分配器,返回指向零值的指针;而make()专用于内置引用类型(切片、映射、通道),负责完成底层结构的初始化。理解其差异是编写健壮Go代码的基础。

核心结论速览

在使用Go时,区分这两个函数的最简方式如下:

  • new(Type):通用内存分配。返回 *Type 指针。内存已分配但内容为零值(Zero Value),未进行对象特有的初始化逻辑。
  • make(Type, ...) :仅限 slice、map、chan。返回 Type 引用(非指针)。不仅分配内存,还完成了特定类型的内部结构初始化(如Map的哈希桶、Slice的底层数组头)。

new(): 通用的零值分配

new 是Go的内建函数之一,其签名简单明了:

func new(Type) *Type

工作原理与示例

new 的主要任务是分配内存并将该内存清零。它并不执行该类型的构造函数或初始化逻辑(Go中自定义类型无传统意义上的构造函数,而是靠工厂函数或字面量语法)。它返回一个指向新分配的、类型为 Type 的变量的指针。

我们可以用标准库逻辑模拟 new 的行为:

// 模拟 new(int)
func newInt() *int {
    var i int // 默认零值 0
    return &i
}

ptr := newInt()
// 等同于 ptr := new(int)

在这个例子中,someInt 是一个指向整数的指针。虽然内存空间已经准备好,但如果 Type 是一个复杂的结构体,new 只会将每个字段重置为其默认零值,而不会自动建立依赖关系(例如指针字段会变为 nil)。

make(): 专用的引用类型构建器

make 也是内建函数,但它的行为比 new 复杂得多。官方文档明确规定:make 只能用于 slice、map 和 chan 这三种内置引用类型。它返回的是这些类型本身(引用/句柄),而不是它们的指针。

1. Slice (切片)

切片的底层包含三个部分:指向数组的指针、长度(len)、容量(cap)。make 会分配底层数组并设置这两项参数。

s := make([]int, 0, 10)
  • 第二个参数(size):指定切片的初始长度。
  • 第三个参数(capacity)(可选):指定切片的容量。如果省略,容量等于长度。

注意:如果省略第三个参数且只传了长度,则 cap 与 len 相等。

2. Map (映射)

Map 是基于哈希表实现的。使用 make 可以预先分配一定数量的哈希桶以减少扩容开销。

m := make(map[string]int, 100)

这里的 100 提示分配器预留容纳约100个键值对的空间。若不提供此参数,Map 仍可正常使用,但在插入大量数据时会频繁触发重新哈希(rehash),影响性能。

3. Chan (通道)

通道用于goroutine间的通信。make 在此处用于创建带缓冲或无缓冲的通道。

c1 := make(chan int)      // 无缓冲
c2 := make(chan int, 100) // 缓冲容量为100

如果传入的缓冲区容量为 0 或被忽略,则该通道是无缓冲的(发送操作将阻塞直到接收者就绪);否则为有缓冲通道。

对比总结

特性 new(Type) make(Type, ...)
返回值类型 *Type (指针) Type (引用类型本身)
适用类型 任何类型 仅 slice, map, chan
是否初始化 仅内存清零 分配内存 + 内部结构初始化

一句话总结:new 用来“申请空白”,make 用来“组装工具”。

以上就是Go语言中new()和make()的核心区别详解,更多关于Go基础知识的学习资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表