go中修改原始变量值必须用&取地址传指针,再用*解引用赋值;结构体需修改时应传指针;nil指针须判空;切片/map/channel传值即可改内容,改变量本身才需指针。

怎么用 & 和 * 修改原始变量的值
Go 中指针的核心就两条:用 & 取地址,用 * 解引用。想改原变量,必须传入它的地址(即指针),并在函数内通过 * 赋值。
常见错误是传值后试图修改形参——这只会改副本,不影响原变量:
func badInc(x int) { x++ } // 无效:x 是 copy
正确做法是传指针:
- 定义函数接收
*int类型参数 - 调用时传
&x,不是x - 函数体内用
*x = *x + 1或*x++修改
修改结构体字段时该传值还是传指针
结构体较大或需修改字段时,必须传指针;否则函数内修改的是整个结构体的拷贝,原结构体不变。
立即学习“go语言免费学习笔记(深入)”;
例如:
type User struct{ Name string; Age int }
func updateUser(u *User) { u.Name = "Alice"; u.Age = 30 } // ✅ 修改生效
func updateUserCopy(u User) { u.Name = "Bob" } // ❌ 原 u.Name 不变
注意:即使结构体很小(如只有两个 int),只要目标是“修改原值”,就该用指针——语义清晰,且避免未来字段扩容带来的隐性 bug。
nil 指针解引用会 panic,怎么安全修改
对 nil 指针执行 * 操作会直接 panic:panic: runtime error: invalid memory address or nil pointer dereference。
在修改前务必检查是否为 nil:
- 函数开头加
if p == nil { return }或返回错误 - 不要假设调用方一定传了有效指针
- 初始化指针建议用
new(T)或&T{},而非裸声明var p *T(此时为 nil)
示例:
func safeInc(p *int) {
if p == nil { return }
*p++
}
切片、map、channel 本身已是引用类型,还用指针吗
不用。切片、map、channel 的底层结构包含指针(如 slice header 里有指向底层数组的指针),所以传值即可修改其内容(如追加元素、增删 key)。
但要注意:如果想修改变量本身(比如让一个 slice 变成 nil,或换一个底层数组),就必须传 *[]T、*map[K]V 等指针:
-
append(s, x)不需要指针——能改内容 -
s = append(s, x)在函数内赋值,不改变调用方的s变量——此时要传*[]int - 同理,
delete(m, k)可以删 key,但m = make(map[int]string)不会影响原 map,除非传*map[int]string
容易忽略的是:函数签名一旦用了指针,调用方就得显式传地址,这点和普通变量一致,别漏掉 &。










