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

长期稳定更新的攒劲资源: >>>点此立即查看<<<
无论 T 的类型是 int、string 还是 struct{},参数 x 均为调用时传入值的一份拷贝。对 x 进行修改不会影响调用方的原始变量。这一概念看似简单,但在实际编码中容易引发问题。
int 类型:副本中存储的是数值(例如 42),修改操作仅作用于副本,原变量保持不变。*int 类型:副本中存储的是地址(例如 0xc00001a080),通过 *x = 100 写入该地址指向的内存——这才是“修改原值”的实际原理。[]byte 或 map[string]int 类型:这些类型底层为包含指针的结构体,因此副本仍指向同一底层数组或哈希表。这依然是值传递,只不过“值”中携带了指针,不应误认为是引用传递。并非“想要修改就使用指针”,而是当不传递指针就无法达成目标时才必须使用。判断依据清晰明确:
swap(a, b *int) 或 json.Unmarshal(data []byte, v interface{}) 要求 v 为指针类型。type Config struct { Data [1e6]byte },传递 Config 会拷贝 1MB 数据,影响性能。func (u *User) SetName(n string) { u.Name = n },若使用值接收者 (u User),修改操作对副本生效,不会影响原变量。将 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 或编写单元测试断言时容易踩坑,值得特别留意。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述