Golang理解指针与值类型对新手的重要性
发布时间 - 2026-01-09 00:00:00 点击率:次Go中func foo(x int)无法修改外部变量,因int是值类型,传参复制副本;修改仅作用于副本,原变量不变。解决方法:返回新值或传*int指针。
为什么 func foo(x int) 改不了外面的变量
因为 int 是值类型,传参时复制一份新值,函数里对 x 的任何修改(比如 x = 42)只作用于副本,原变量完全不受影响。这不是 bug,是 Go 的设计原则:默认不共享、不隐式修改。
常见错误现象:写了个 increment 函数想让数字加 1,调用完发现变量没变。
-
解决方法:要么返回新值(
return x + 1),要么传指针(*int) - 注意:返回新值更符合函数式风格;传指针则意味着你明确要修改原数据
- 性能上,小类型(
int,bool,struct{a,b int})传值开销小;大 struct 或 slice 底层数据多时,传指针反而省拷贝
& 和 * 不是“C 风格语法糖”,而是类型系统的一部分
Go 的 *T 是一个独立类型,不是修饰符。比如 *string 和 string 类型不同,不能混用;nil 对 *string 合法,对 string 不合法。
容易踩的坑:
- 声明指针变量但没初始化(
var p *int),此时p == nil,解引用会 panic:fmt.Println(*p) - 把值类型地址取给指针后,原变量生命周期结束,指针就悬空(比如在函数内取局部变量地址并返回)
-
new(T)返回*T,等价于var t T; return &t,但初学者常误以为它类似 C 的 malloc
slice、map、channel 为什么“像指针”但又不是指针
它们底层都包含指向堆内存的指针字段(比如 slice 有 ptr, len, cap),所以传参时虽然也是值传递,但 ptr 字段被复制了,因此能修改底层数组内容。但这不等于它们是指针类型 —— 你不能对 map 做 &m 然后传 *map[string]int,编译会报错。
关键区别:
- 可以对 slice 元素赋值(
s[0] = 1),是因为它复制了指向底层数组的指针 - 但重新赋值整个 slice(
s = append(s, 1))可能触发扩容,生成新底层数组,此时原 slice 变量不会同步更新 - map 和 channel 同理:能增删元素,但不能通过传参让调用方看到
m = make(map[int]string)这样的重赋值
什么时候该用指针?看三个实际信号
不是“为了节省内存”或“看起来高级”,而是由语义和需求驱动:
- 需要函数修改调用方的变量 → 用
*T - 结构体过大(比如含几百字节字段),且频繁传参 → 用
*S避免拷贝(但先 profile,别过早优化) - 方法接收者需修改结构体字段(如
func (p *Person) SetName(n string))→ 必须用指针接收者,否则改的是副本
新手最容易忽略的一点:即使结构体很小,只要方法要修改字段,就必须用指针接收者。否则代码能编译,但字段根本没变 —— 这类 bug 很难一眼发现。
# go
# golang
# app
# 字节
# 解决方法
# 区别
# 为什么
# String
# 局部变量
# 结构体
# bool
# int
# 指针
# 堆
# 值类型
# 指针类型
# Struct
# var
# 值传递
# len
# cap
# nil
# append
# map
# channel
# bug
# 没变
# 的是
# 是一个
# 很难
# 什么时候
# 是由
# 你不
# 这类
# 不受
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
青岛网站建设如何选择本地服务器?
如何撰写建站申请书?关键要点有哪些?
如何在宝塔面板创建新站点?
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
Python3.6正式版新特性预览
如何在云虚拟主机上快速搭建个人网站?
JavaScript中如何操作剪贴板_ClipboardAPI怎么用
详解CentOS6.5 安装 MySQL5.1.71的方法
个人摄影网站制作流程,摄影爱好者都去什么网站?
如何在IIS服务器上快速部署高效网站?
网站图片在线制作软件,怎么在图片上做链接?
敲碗10年!Mac系列传将迎来「触控与联网」双革新
Laravel如何实现API速率限制?(Rate Limiting教程)
深入理解Android中的xmlns:tools属性
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
如何在云指建站中生成FTP站点?
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
Laravel如何与Inertia.js和Vue/React构建现代单页应用
如何在建站之星绑定自定义域名?
浅谈Javascript中的Label语句
三星网站视频制作教程下载,三星w23网页如何全屏?
香港服务器WordPress建站指南:SEO优化与高效部署策略
高防服务器租用如何选择配置与防御等级?
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
如何在景安服务器上快速搭建个人网站?
Laravel如何处理和验证JSON类型的数据库字段
Swift开发中switch语句值绑定模式
Laravel如何实现用户注册和登录?(Auth脚手架指南)
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例
如何快速生成高效建站系统源代码?
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
如何在不使用负向后查找的情况下匹配特定条件前的换行符
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
如何在VPS电脑上快速搭建网站?
新三国志曹操传主线渭水交兵攻略
南京网站制作费用,南京远驱官方网站?
黑客如何通过漏洞一步步攻陷网站服务器?
Laravel如何处理表单验证?(Requests代码示例)
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?

