Go中值类型变量函数内不可修改,须传指针;T声明指针类型,&v取地址,p解引用;struct传值改副本,须传Struct;切片是值类型,append扩容需返回或传[]T。

Go 中值类型变量不能被函数内修改,除非传指针
Go 函数参数是值传递,哪怕传的是 int、string、struct 这类值类型,函数内部拿到的也只是副本。原变量不会变。想改原变量,必须传它的地址——也就是指针。
*T 和 &v 是配对操作:取地址和解引用
声明指针类型用 *T(比如 *int),获取变量地址用 &v,通过指针修改值用 *p = x。漏掉 * 或多写 * 都会编译报错或行为异常。
-
&v返回变量v的内存地址,类型是*T -
*p表示“取指针p指向的值”,可读可写 - 声明指针变量时未初始化,值为
nil;解引用nil指针会 panic
修改 struct 字段必须传结构体指针,否则改的是副本
struct 是值类型,哪怕它很大,传参时也复制整个结构体。常见错误是定义一个修改字段的函数却传了 struct 本身,结果调用后字段没变。
type User struct {
Name string
Age int
}
func updateUser(u User) { // ❌ 错误:u 是副本
u.Name = "Alice"
u.Age = 30
}
func updateUserPtr(u *User) { // ✅ 正确:u 指向原变量
u.Name = "Alice"
u.Age = 30
}
func main() {
u := User{Name: "Bob", Age: 25}
updateUser(u) // u 不变
updateUserPtr(&u) // u.Name 变成 "Alice"
}
切片、map、channel 是引用类型,但底层数组仍需注意指针语义
切片本身是值类型(含 pointer、len、cap 三个字段),所以传切片不等于传底层数组指针。若函数内做了 append 导致扩容,新底层数组不会反映到原切片上。需要返回新切片或传 *[]T 才能保证修改生效。
立即学习“go语言免费学习笔记(深入)”;
- 只修改已有元素(如
s[0] = x):无需指针,因为 pointer 字段指向同一数组 - 追加元素且可能扩容(
append(s, x)):原切片变量不变,必须用返回值或*[]T - 想让函数能重分配底层数组并更新原变量,得传
*[]int,再用*s = append(*s, x)










