首页 > 后端开发 > Golang > 如何在 Go 中部分解码和更新 JSON 对象?

如何在 Go 中部分解码和更新 JSON 对象?

Barbara Streisand
发布: 2024-12-25 00:29:16
原创
850 人浏览过

How to Partially Decode and Update JSON Objects in Go?

Go 中的部分 JSON 解码和更新

在某些场景下,仅解码和更新 JSON 对象的特定值时会出现常见问题,特别是当完整的对象结构未知时。 Go中的标准encoding/json包会截断结构体中未提供的字段,导致数据丢失。

使用json.RawMessage的解决方案

这个问题的解决方案是将自定义结构与 json.RawMessage 结合起来。这种方法允许我们将整个数据保存到原始字段中以进行编码/解码。

Go 中的 json.RawMessage 类型是一个 []byte 值,可以保存任意 JSON 数据。对于这样的情况很有用,我们只知道 JSON 结构的一部分,并希望保留未知部分。

示例代码

package main

import (
    "encoding/json"
    "log"
)

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
}

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)
}

func main() {
    before := []byte(`{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}`)
    log.Println("before: ", string(before))

    // decode
    color := new(Color)
    err := json.Unmarshal(before, color)
    if err != nil {
        log.Fatal(err)
    }

    // modify fields of interest
    color.Space = "RGB"

    // encode
    after, err := json.Marshal(color)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("after:  ", string(after))
}
登录后复制

输出

before:  {"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}}
after:   {"Point":{"Y":255,"Cb":0,"Cr":-10},"Space":"RGB"}
登录后复制

此解决方案允许我们仅解码和更新特定值(在在本例中为 Space),同时保留 JSON 对象中的所有其他未知数据。需要注意的是,这种方法不会保留输出中的键顺序或缩进。

以上是如何在 Go 中部分解码和更新 JSON 对象?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板