首页 >后端开发 >Golang >如何在 Go 中部分解码和更新 JSON 数据而不丢失未知字段?

如何在 Go 中部分解码和更新 JSON 数据而不丢失未知字段?

Patricia Arquette
Patricia Arquette原创
2024-12-24 20:44:17697浏览

How to Partially Decode and Update JSON Data in Go Without Losing Unknown Fields?

在 Go 中部分解码和更新 JSON

处理 JSON 数据时,有时需要仅修改特定值而不丢失现有结构。如果您不知道 JSON 对象的整个结构,这可能会很有挑战性,因为 Go 的encoding/json 包会截断目标结构中未包含的字段。

本文探讨了一种利用常规结构组合的技术和 json.RawMessage 实现部分解码和更新,且不会丢失未知信息。

部分解码

部分解码的关键解码是将整个 JSON 数据保存在原始字段(例如,map[string]json.RawMessage)中,并有选择地将特定字段解组到结构中。它是这样完成的:

import "encoding/json"

type Color struct {
    Space string
    raw   map[string]json.RawMessage
}

func (c *Color) UnmarshalJSON(bytes []byte) error {
    if err := json.Unmarshal(bytes, &c.raw); err != nil {
        return err
    }
    if space, ok := c.raw["Space"]; ok {
        if err := json.Unmarshal(space, &c.Space); err != nil {
            return err
        }
    }
    return nil
}

这里,UnmarshalJSON 将整个 JSON 数据检索到 c.raw,然后将 Space 字段解组到 c.Space。

修改已知字段

部分解码 JSON 数据后,您可以将特定字段修改为需要。

编组和保留

修改已知字段后,您需要将更新的 Color 结构编组回 JSON。为了保留现有结构并避免截断,您可以编写自定义 MarshalJSON 方法:

func (c *Color) MarshalJSON() ([]byte, error) {
    bytes, err := json.Marshal(c.Space)
    if err != nil {
        return nil, err
    }
    c.raw["Space"] = json.RawMessage(bytes)
    return json.Marshal(c.raw)
}

在 MarshalJSON 中,您对修改后的 Space 字段进行编组,然后在执行最终编组之前将其嵌入到原始映射中。

结论

该技术允许您修改 JSON 数据中的特定值而不丢失未知信息,使其适合适用于完整 JSON 结构不可用或可能发生更改的场景。

以上是如何在 Go 中部分解码和更新 JSON 数据而不丢失未知字段?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn