信息发布→ 登录 注册 退出

如何在Golang中修改值类型数据_使用指针改变变量值

发布时间:2026-01-10

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

Go 中值类型变量不能被函数内修改,除非传指针

Go 函数参数是值传递,哪怕传的是 intstringstruct 这类值类型,函数内部拿到的也只是副本。原变量不会变。想改原变量,必须传它的地址——也就是指针。

*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 才能保证修改生效。

  • 只修改已有元素(如 s[0] = x):无需指针,因为 pointer 字段指向同一数组
  • 追加元素且可能扩容(append(s, x)):原切片变量不变,必须用返回值或 *[]T
  • 想让函数能重分配底层数组并更新原变量,得传 *[]int,再用 *s = append(*s, x)
真正容易忽略的是:即使你用了指针,如果中间经过多次赋值或 channel 发送,指针值可能被复制,而你误以为还在操作原地址。每次传递指针前,确认它是否仍指向你期望的那个变量。
标签:# len  # 不等于  # 而你  # 报错  # 再用  # 想让  # 这类  # 用了  # 已有  # 还在  # 的是  # channel  # map  # append  # nil  # cap  # go  # 切片  # pointer  # 值传递  # Struct  # 指针类型  # 引用类型  # 值类型  # 指针  # int  # 结构体  # String  # ai  # app  # golang  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!