在 Go 中修改结构体字段需使用指针:传结构体指针、函数参数声明为指针类型、方法接收者用指针,且操作对象必须可寻址(如变量、slice 元素),map 元素不可取地址。
在 Go 中,通过指针操作结构体可以修改其内部字段,关键在于传递结构体指针而非值拷贝。
Go 默认按值传递,传结构体时会复制整个实例;而传 *StructType 时,函数内对字段的赋值会作用于原始结构体。
ptr := &user)func updateUser(u *User)),调用时传 &user
容易混淆的是:变量本身是指针时,不能再对它用 &;而普通变量必须先取地址才能赋给指针变量。
u := User{Name: "A"}; ptr := &&u(多了一个 &)u := User{Name: "A"}; u.Name = "B" 在函数里这样写,但参数是 u User(值拷贝,不改原值)func setName(u *User, name
string) { u.Name = name },调用 setName(&user, "New")
只要路径上的每一层都可寻址(即不是从 map 或 slice 直接取的临时值),就能用指针链式修改。
type Profile struct { Info *Info },若 p := &Profile{Info: &Info{Age: 20}},则 p.Info.Age = 25 有效s := []User{{Name: "X"}}; ptr := &s[0] 合法;但 m := map[string]User{"k": {Name: "Y"}}; ptr := &m["k"] 编译报错(map 元素不可寻址)为结构体定义指针接收者方法后,调用该方法的对象无论是变量还是指针,Go 都会自动处理解引用。
func (u *User) SetName(n string) { u.Name = n }u := User{}; u.SetName("Alice") ✅ 自动取地址up := &User{}; up.SetName("Bob") ✅ 本来就是指针,直接调用func (u User))无法修改原结构体字段不复杂但容易忽略。核心就一条:想改原结构体,函数参数、变量声明、方法接收者,统一用指针类型,并确保操作对象是可寻址的。