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

Go json.Unmarshal后用指针修改map值时出现无法取地址错误问题

报错原因

Go 语言中map 类型的元素值是不可寻址的,这是报错的核心原因。
map 的底层实现是哈希表,运行时会动态扩容、调整元素的存储位置,Go 语言直接禁止了对 map 元素取地址的操作,避免指针指向无效的内存地址。你尝试取 gold 字段的地址时,该字段属于 map 的元素,所以编译器直接抛出错误。
此外你反序列化后 gold 字段的默认类型是 interface{},就算可以取到地址,后续操作也需要额外做类型断言,反而会增加代码复杂度。

解决方法

有两种常用的方案可以简化嵌套字段的操作:

方案1:持有最内层嵌套的 map 引用

map 本身是引用类型,你只需要拿到存储 gold 字段的最内层 map,后续直接操作这个 map 变量就可以同步修改原数据,不需要额外取指针:

inventory := result["player"].(map[string]interface{})["inventory"].(map[string]interface{})
// 后续直接操作 inventory 即可修改原数据
inventory["gold"] = 100
inventory["diamond"] = 20

这种方式代码改动量最小,性能损耗可以忽略,是临时处理非固定结构 JSON 时最常用的方案。

方案2:提前定义结构体做反序列化(推荐)

如果 JSON 结构是固定的,提前定义对应结构体,反序列化时直接解析到结构体实例中,后续可以直接拿到字段指针做操作:

// 定义对应JSON结构的结构体
type PlayerData struct {
    Player struct {
        Inventory struct {
            Gold int `json:"gold"`
        } `json:"inventory"`
    } `json:"player"`
}

// 反序列化逻辑
var result PlayerData
json.Unmarshal([]byte(byteValue), &result)

// 直接取字段指针操作
gold := &result.Player.Inventory.Gold
*gold = 100

这种方式可以完全避免大量重复的类型断言代码,编译期就能检查类型错误,代码可维护性更高,适合业务场景下固定结构的 JSON 处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 04:36:04