You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go中调用map存储的指针接收者方法为何未修改原对象状态

问题根本原因

你猜测的方向是对的,核心问题出在方法值绑定的接收者是创建时的实例指针,而你返回值类型时发生了实例拷贝:

  1. 在New函数内部,你创建的是局部值类型实例p,执行p.M["1"] = p.Add时,因为Add是指针接收者方法,Go会自动对当前可寻址的局部p取指针作为该方法值的接收者,也就是这个Add方法已经绑定了New函数内局部p的内存地址。
  2. 你的New函数返回的是Person值类型,执行return p时会对局部p做值拷贝,返回给main函数的是一个全新的实例,和New内部的局部p是两个完全独立的内存对象。只有map作为引用类型被拷贝了指针,所以两个实例共享同一个M map。
  3. 后续main里调用Run方法时,接收者是main里新实例的指针,修改的是新实例的Age;而调用M里存的Add方法时,用的还是当初绑定的New内部旧实例的指针,修改的是旧实例的Age,自然不会同步到main里的新实例上。

修复方案

只需要把New函数的返回值改为指针类型即可,避免实例拷贝,让方法值绑定的接收者和main里使用的实例是同一个:

// 修改New函数返回值为*Person
func New() *Person {
    p := &Person{1, make(map[string]func())}
    p.M["1"] = p.Add
    return p
}

修改后运行结果就会符合预期:

age before 1
Age before mutating in Run 1
Age before mutating in Add 2
Age after mutating in Add 3
Age after mutating in Run 3
age after 3

内容的提问来源于stack exchange,提问作者abhijat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:06:04