Golang中new与make的区别及使用场景

纸上星河
纸上星河
发布时间:2026-10-16| 2人浏览过
原创

在Golang开发中,正确使用new与make函数是避免空指针异常的关键。本文详细对比了new(仅分配并清零)与make(分配且初始化slice/map/channel)的区别,通过代码示例演示了各自的操作入口、参数要求及完成状态,帮助开发者准确区分使用场景。

操作目标与结果

在Go语言中,内存分配主要通过 new 和 make 两个内建原语实现。明确它们的区别可以帮助开发者避免常见的 panic: runtime error: invalid memory address or nil pointer dereference 错误。核心区别在于:

  • new(T):分配零值内存,返回指向该类型的指针 *T。适用于所有类型。
  • make(T, args):分配并初始化特定类型(slice, map, channel),返回类型为 T 的引用类型本身。不返回指针。

准备条件

  1. 安装 Go 语言环境(建议版本 1.11+)。
  2. 配置编辑器或IDE以支持 Go 语法高亮和代码补全。
  3. 确保了解 Go 的基本指针概念与引用类型机制。

真实操作顺序

第1步:使用new进行基础内存分配

目的:为基本数据类型分配内存并初始化为零值。
入口:调用内建函数 new(Type)。
动作:new 在堆上分配内存,并将内容置为零值(如 int 为 0,string 为空字符串)。它返回一个指向新分配的类型的指针。

var v *int
// 错误用法:直接赋值会导致panic
// *v = 8 

// 正确用法:使用new分配内存
v = new(int)
*v = 8
fmt.Println(*v) // 输出: 8

重要参数:唯一参数为类型名 Type。
完成状态:指针变量 v 不再为 nil,指向一块已分配内存,其值为对应类型的零值。

第2步:处理复合类型与引用类型的陷阱

目的:理解为什么对数组用 new 可行,而对 slice/map/channel 用 new 会失败。
入口:尝试对引用类型使用 new。
动作:虽然 new 可以分配内存,但 slice、map 和 channel 的内部结构需要额外初始化(如 slice 的长度和容量记录,map 的桶结构)。仅分配内存而不初始化内部结构会导致后续操作 panic。

示例:Slice 的错误用法

av := new([]int) // av是指向slice的指针,*av是nil slice
(*av)[0] = 8    // Panic: index out of range

示例:Map 的错误用法

mv := new(map[string]string) // mv是指向map的指针,*mv是nil map
(*mv)["key"] = "value"       // Panic: assignment to entry in nil map

第3步:使用make初始化切片、映射和通道

目的:正确初始化引用类型,使其处于可用状态。
入口:调用内建函数 make(Type, sizeOrCapacity...)。
动作:make 不仅分配内存,还初始化数据结构。它返回的是类型本身(非指针),例如 []int、map[K]V、chan T。

完整代码示例:

// 初始化Slice
av := make([]int, 5) // 长度5,容量5,元素为零值0
av[0] = 1
fmt.Printf("av: %#v\n", av) // []int{1, 0, 0, 0, 0}

// 初始化Map
mv := make(map[string]string)
mv["m"] = "m"
fmt.Printf("mv: %#v\n", mv) // map[m:m]

// 初始化Channel
chv := make(chan string)
go func() {
    chv <- "Ping!"
}()
msg := <-chv
fmt.Println(msg) // Ping!
close(chv)

重要参数: 1. Type: 必须是 slice, map 或 channel。 2. Size/Capacity: Slice 需指定长度(第二个参数可选容量);Map 无需大小;Channel 无参数或缓冲大小。

完成状态:变量可直接进行索引、赋值或收发操作,不会触发 nil 相关 panic。

第4步:混合使用new与make(进阶场景)

目的:当需要获取指向已初始化引用类型的指针时使用。
入口:先 new 后 make。
动作:先用 new 获得指针空间,再用 make 初始化指针指向的内容。

var mv *map[string]string
mv = new(map[string]string)   // mv = (*map[string]string)(nil)
(*mv) = make(map[string]string) // 初始化地图
(*mv)["a"] = "a"              // 安全赋值

注意:大多数情况下,直接使用返回值即可,无需手动管理指针。

完成判断与排错

  • 成功标准:程序运行无 panic,数据按预期存入或读取。
  • 常见错误排查:
    • panic: assignment to entry in nil map:使用了 new 而非 make 初始化 map,或直接声明未初始化 map 并赋值。
    • panic: index out of range:使用了 new 而非 make 初始化 slice,导致底层数组未创建。
    • invalid operation:试图向 *chan(指针类型的通道)发送消息,应使用 chan。

简要总结

new 是通用的内存分配器,返回指针,仅清零;make 是专用初始化器,返回引用类型本身,负责构建 slice/map/channel 的内部结构。记住口诀:“new 给指针,make 给本体”。以上就是Golang的new与make区别的详细内容,更多关于Go语言内存管理的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。