如何理解Golang指针与值类型区别_Golang内存模型与数据传递机制说明
发布时间 - 2026-02-02 00:00:00 点击率:次Go中所有参数都是值传递,传struct时修改副本不影响原变量;需用指针接收者才能修改原值;切片/map/channel是含指针的值类型;是否用指针取决于是否需修改、大小及接口实现。
为什么传 struct 时函数里改了字段,外面却没变?
因为 Go 所有参数都是值传递——func f(s MyStruct) 传进去的是整个 MyStruct 的副本,函数内修改的只是副本字段,原变量毫发无伤。
- 想让外部看到修改,必须用指针:
func f(s *MyStruct),然后在函数里写s.Field = "new" - 哪怕结构体只有两个
int字段,只要方法需要改状态(比如user.IncreaseLoginCount()),就该用指针接收者 - 常见错误现象:
user.SetName("Alice")调用后user.Name还是空字符串——十有八九接收者写成了func (u User) SetName(n string),而不是func (u *User) SetName(n string)
切片、map、channel 为啥“像引用”但又不是引用类型?
它们是「含指针的值类型」:变量本身是值(比如 sliceHeader 结构体),但内部字段存着底层数组/哈希表的地址。所以传参时虽拷贝 header,但底层数据仍共享。
-
append可能扩容并返回新 slice,原变量不变;而map["k"] = v直接生效,因 map header 里的指针指向同一 hash 表 - 误以为「map 是引用类型」会导致误判:把 map 当参数传进函数,函数里清空它(
clear(m)),调用方确实看到空了;但若函数里做了m = make(map[string]int),这只会改副本 header,不影响外层 - 安全做法:需要保证行为可预测时,显式传
*map或*[]T(虽然极少这么做)
nil 指针解引用 panic 和空接口赋值失败,根源都是同一套规则
Go 中一切皆值传递,但「值」的内容决定你能干什么:nil 是 *T 类型的零值,代表「地址为空」;而空接口 interface{} 存的是(类型, 数据)对,当

nil 时,类型信息可能丢失。
-
var p *string; fmt.Println(*p)→ 直接 panic:不能解引用nil指针 -
var s *string; var i interface{} = s; fmt.Println(i == nil)→ 输出false!因为i存的是 (*string,nil),类型非空,整体不等于nil - 判断指针是否有效,永远先做
if p != nil;判断接口是否为 nil,要拆成if i == nil || reflect.ValueOf(i).IsNil()(或更稳妥地用类型断言)
什么时候该用指针,什么时候死守值类型?
核心就看三件事:要不要改原值、对象大不大、接不接口。
- 要改原值 → 必须用指针(
*T参数或接收者) - 结构体字段总大小 > 16 字节(如含
[32]byte或多个string)→ 优先指针,避免复制开销 - 实现了某个接口?注意方法集:如果只有
func (t *T) Foo(),那T{}值本身无法赋给该接口变量,必须传&T{} - 小而只读的数据(
int、time.Time、轻量struct{ ID int; Name string })→ 传值更清晰,无 nil 风险,GC 压力小
最容易被忽略的一点:即使结构体很小,只要它和指针接收者的方法混用(比如标准库 sync.Mutex),就必须统一用指针——否则调用 Lock() 时传值会触发拷贝,锁的不是同一个实例。
# go
# golang
# app
# 字节
# 区别
# 标准库
# 为什么
# golang指针
# String
# if
# 字符串
# 结构体
# int
# 指针
# 接口
# 值类型
# 引用类型
# Struct
# Interface
# var
# 值传递
# 切片
# nil
# append
# map
# channel
# 对象
# 的是
# 都是
# 什么时候
# 原值
# 该用
# 多个
# 你能
# 这只
# 这么做
# 就看
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
Java解压缩zip - 解压缩多个文件或文件夹实例
如何用搬瓦工VPS快速搭建个人网站?
android nfc常用标签读取总结
Python文件操作最佳实践_稳定性说明【指导】
微信小程序 五星评分(包括半颗星评分)实例代码
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
Laravel如何创建自定义Artisan命令?(代码示例)
python中快速进行多个字符替换的方法小结
在线制作视频网站免费,都有哪些好的动漫网站?
Java类加载基本过程详细介绍
网站制作报价单模板图片,小松挖机官方网站报价?
如何挑选优质建站一级代理提升网站排名?
如何在云主机上快速搭建网站?
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
JavaScript如何操作视频_媒体API怎么控制播放
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
如何用狗爹虚拟主机快速搭建网站?
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
如何快速搭建高效香港服务器网站?
网站优化排名时,需要考虑哪些问题呢?
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
高防服务器:AI智能防御DDoS攻击与数据安全保障
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
网站建设保证美观性,需要考虑的几点问题!
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
高端企业智能建站程序:SEO优化与响应式模板定制开发
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
如何撰写建站申请书?关键要点有哪些?
EditPlus中的正则表达式实战(5)
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
Linux系统命令中tree命令详解
如何快速搭建虚拟主机网站?新手必看指南
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
Android使用GridView实现日历的简单功能
Python自动化办公教程_ExcelWordPDF批量处理案例
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
iOS验证手机号的正则表达式
Laravel如何使用withoutEvents方法临时禁用模型事件
如何续费美橙建站之星域名及服务?

