Go函数参数传递:值传递本质与指针传递适用场景
Go函数参数始终是值传递,指针传递的本质是传递地址值,通过解引用操作同一内存。必须使用指针的场景包括:需修改原变量、大结构体避免复制、方法接收者需写字段。常见陷阱:nil指针解引用引发panic,slice的append不改变原切片。
Go 语言中,函数参数传递始终遵循值传递规则,这一点没有例外。所谓“通过指针可以修改原值”,其本质在于传递的是地址这个值,通过解引用操作同一块内存——地址本身也是一个值,但它指向了原始变量所在的内存位置。

func f(x T) 中的 x 永远是副本
无论 T 是 int、string 还是 struct{} 类型,x 都是调用时传入值的一份副本。修改 x 不会影响调用方的原始变量。这个道理听起来简单,但在实际编码中经常容易踩坑。
- 传
int:副本里存储的是数字(比如42),修改它只是在修改副本,原始变量纹丝不动。 - 传
*int:副本里存储的是地址(比如0xc00001a080),通过*x = 100写入的是该地址指向的内存——这才是“修改原值”的真相。 - 传
[]byte或map[string]int:它们底层是包含指针的结构体,因此副本仍然指向同一底层数组或哈希表。但这仍然是值传递,只是“值”中包含了指针,切勿误认为是引用传递。
何时必须使用 *T 而非 T
不是“想改就用指针”,而是不传指针就无法达成目标时才必须使用。判断标准其实很清晰:
- 需要修改调用方的原始变量:比如
swap(a, b *int)或json.Unmarshal(data []byte, v interface{})要求v是指针。 - 结构体很大(字段多、包含大 slice/map、或数组长度大):避免复制开销。例如
type Config struct { Data [1e6]byte },传递Config会拷贝 1MB,性能堪忧。 - 方法接收者需要写字段:如
func (u *User) SetName(n string) { u.Name = n },值接收者(u User)修改了也无效,因为副本不会影响原变量。
常见 panic 及误判场景
向函数传递 nil 指针后再解引用,会直接触发 panic: runtime error: invalid memory address or nil pointer dereference。这是新手最容易犯的错误之一。
- 传递
nil *User然后执行u.Name = "x"→ panic。 - 但传递
User{}(零值)是安全的,即使字段是空 slice 或 map,也不会触发 panic。 - 不要认为“
slice是引用类型就能修改原 slice”:对s执行s = append(s, x)不会影响调用方,因为append可能分配新的底层数组,只修改了副本中的ptr。这是 slice 的经典陷阱。
真正容易被忽略的是:切片、map、channel 的“可变性”来源于其内部指针字段,而非语言层面的引用传递;而 *[]T、*map[K]V 这类指针类型本身可比较,但 []T 和 map[K]V 不可比较——这一点在作为 map key 或进行单元测试断言时经常踩坑,值得多加留意。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Go语言AES混淆加密解密敏感数据详解
Go语言AES加密需注意:密钥长度必须为16、24或32字节,否则会引发panic;CBC模式解密乱码常因IV或PKCS7填充错误;GCM模式中nonce不可重用,否则密钥可被恢复;ECB模式因明文块输出固定密文,存在安全风险,不建议使用。
C++ std::atomic::wait高性能轮询等待原子变量状态变化
C++20的std::atomic::wait是轻量级等待机制,需GCC11+ Clang12+及glibc≥2 34,macOS不支持。需与notify配对,注意内存序,循环检查防虚假唤醒。超时版本精度有限,高性能关键在notify时机与内存序正确性。
VSCode左侧边栏不见了?快速找回方法
按Ctrl+B或Cmd+B可恢复被误触隐藏的侧边栏。若无效,需检查窗口焦点是否在编辑器、是否处于全屏或Zen模式、workbench activityBar visible配置项、扩展冲突以及远程环境同步问题,并逐一排查。
VSCode中利用Node批量修改多媒体文件元数据标签
music-metadata库支持跨格式读写MP3、FLAC、M4A、WAV等音频元数据,需先用parseFile()初始化,再调用writeMetadata()写入。批量修改前必须验证写入支持,封面图片需为Uint8Array格式。在VSCode终端运行脚本比插件更可控,处理中文路径时需切换终端代码页为UTF-8并指定ID3v2 3版本以避免乱码。
用Composer引入PHP-Console-Highlighter在终端高亮代码段
php-console-highlighter已废弃且不兼容现代PHP,无法通过Composer安装。推荐使用clue rainbow库,执行composerrequire后调用静态方法高亮代码。若需原库,须手动下载并require_once,但存在兼容问题,不推荐生产环境。
- 热门数据榜
相关攻略
2026-07-13 06:53
2026-07-13 06:53
2026-07-13 06:53
2026-07-13 06:53
2026-07-13 06:53
2026-07-13 06:52
2026-07-13 06:52
2026-07-13 06:52
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

