如何在Golang中理解指针和内存分配_使用new和make创建变量
发布时间 - 2025-12-31 00:00:00 点击率:次new用于为任意类型分配零值内存并返回* T,make专为slice/map/channel初始化并返回T本身;指针是存地址的变量,需用&取址才能有效使用。
在 Go 语言中,理解指针和内存分配的关键不在于死记语法,而在于搞清 new 和 make 分别解决什么问题、作用于哪些类型、返回什么——它们不是可互换的“创建变量”工具,而是面向不同场景的内存初始化机制。
指针本质:保存地址的变量,不是“指向对象”的魔法
Go 中的指针就是存储另一个变量内存地址的变量,它本身也占内存(通常是 8 字节)。声明 var p *int 只是定义了一个未初始化的指针(值为 nil),此时它不指向任何有效内存。要让它真正可用,必须让它指向一个已分配的 int 值:
-
x := 42→ 在栈上分配一个 int,值为 42 -
p := &x→&x取出 x 的地址,赋给 p;p 现在持有该地址 -
*p = 100→ 解引用,把 100 写入 p 所指的那块内存(也就是修改了 x)
注意:& 操作符要求操作数必须是“可寻址的”(比如变量、结构体字段、切片元素),不能对字面量或函数调用结果取地址(如 &42 或 
&fmt.Sprintf(...) 是非法的)。
new(T):为任意类型 T 分配零值内存,返回 *T
new 是一个内置函数,功能非常单一:申请一块足够存放类型 T 的内存,将这块内存按 T 的零值清零(比如 int→0,string→"",*int→nil,struct→各字段均为零值),然后返回指向它的指针 *T。
- 适用于所有类型:基本类型、结构体、数组、指针等
- 不支持 slice、map、channel —— 因为这些是引用类型,需要额外的运行时初始化(比如设置底层数组、哈希表、队列等)
- 返回的是指针,且所指内存内容一定是零值,无法自定义初始值
示例:
p := new(int) // 分配一个 int,值为 0,p 类型是 *int,等价于 var v int; p := &vp := new([3]int) // 分配一个 [3]int 数组,每个元素为 0,p 类型是 *[3]int
make(T, args...):只为 slice/map/channel 初始化,返回 T(非指针)
make 是专为三种引用类型设计的内置函数,它不只是分配内存,还要完成类型特定的初始化工作,并返回一个**已经就绪可用的值**(不是指针):
-
make([]T, len)→ 分配底层数组,创建 slice header(包含指针、长度、容量),返回[]T -
make(map[K]V)→ 初始化哈希表结构,返回map[K]V -
make(chan T, cap)→ 创建带缓冲或无缓冲 channel,返回chan T
关键点:
- 只能用于 slice、map、channel,对其他类型调用会编译错误
- 返回的是值本身(如
[]int),不是指针;你不需要也不应该对 make 的结果再取地址来“获得指针” - 它内部做了比
new更多的事:比如make(map[string]int)不仅分配内存,还构建了哈希桶、设置了负载因子等运行时结构
对比记忆:
s := make([]int, 5) // ✅ 正确:创建长度为 5 的切片,元素全为 0s := new([]int) // ❌ 编译失败:[]int 不在 make 支持列表中,但 new 虽然能通过,返回的是 *[]int(指向一个 nil 切片),几乎没用
m := make(map[string]int // ✅ 正确
m := new(map[string]int // ❌ 编译失败:map 不支持 new
何时用哪个?看你要什么
一句话判断:
- 你需要一个**刚分配、已清零、可直接解引用的指针** → 用
new(T) - 你需要一个**已初始化、可立即使用的 slice/map/channel** → 用
make(T, ...) - 你只是想获取一个已有变量的地址 → 直接用
&x,不用 new 也不用 make - 你要初始化一个结构体并获取其指针,且希望字段有非零初值 → 用字面量加取地址:
p := &MyStruct{Field: "hello"},而不是 new + 逐个赋值
常见误区:以为 make 返回指针(它不返回)、以为 new 能初始化 map(它不能)、以为 make([]T, 0) 和 new([]T) 效果类似(前者是空切片,后者是 nil 切片,行为不同)。
# go
# golang
# 字节
# 工具
# 栈
# 编译错误
# String
# 结构体
# int
# 指针
# 引用类型
# Struct
# var
# 切片
# len
# cap
# nil
# map
# channel
# 对象
# 的是
# 它不
# 值为
# 不支持
# 专为
# 是一个
# 清零
# 也不
# 你要
# 已有
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】
网站制作软件免费下载安装,有哪些免费下载的软件网站?
装修招标网站设计制作流程,装修招标流程?
Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区
网站制作软件有哪些,制图软件有哪些?
音响网站制作视频教程,隆霸音响官方网站?
打开php文件提示内存不足_怎么调整php内存限制【解决方案】
EditPlus中的正则表达式实战(6)
如何用景安虚拟主机手机版绑定域名建站?
微信小程序 canvas开发实例及注意事项
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
如何确保FTP站点访问权限与数据传输安全?
Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全
如何在橙子建站上传落地页?操作指南详解
安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
英语简历制作免费网站推荐,如何将简历翻译成英文?
,怎么在广州志愿者网站注册?
Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】
香港服务器网站推广:SEO优化与外贸独立站搭建策略
重庆市网站制作公司,重庆招聘网站哪个好?
清除minerd进程的简单方法
HTML 中动态设置元素 name 属性的正确语法详解
Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
Laravel安装步骤详细教程_Laravel环境搭建指南
如何快速登录WAP自助建站平台?
laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法
佛山网站制作系统,佛山企业变更地址网上办理步骤?
Linux后台任务运行方法_nohup与&使用技巧【技巧】
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
浅谈redis在项目中的应用
如何基于PHP生成高效IDC网络公司建站源码?
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
如何用美橙互联一键搭建多站合一网站?
Linux系统运维自动化项目教程_Ansible批量管理实战
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
使用豆包 AI 辅助进行简单网页 HTML 结构设计
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
如何在建站之星网店版论坛获取技术支持?
如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程
百度浏览器网页无法复制文字怎么办 百度浏览器复制修复
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
详解Oracle修改字段类型方法总结
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
如何快速生成橙子建站落地页链接?

