json - 重命名的 JSON 字段

标签 json go

我们想在生产中将 JSON 字段 value 重命名为 v。在我们所有的用户都使用新结构之前,我们将继续将旧的 JSON 结构添加到我们的代码中。所以我们也想处理这个问题。

如果您注意到,First 是原始结构,Second 是新结构。为了处理这两种结构,我创建了一个 MyStruct 并基于 version,我将 OldValue 复制到 Value

if m.Version <= 1 {
    m.Value = m.OldValue
}

有没有更好的方法来处理这个问题,而不是我的代码。

Go Playground Link

package main

import "fmt"
import "encoding/json"
import "log"

type First struct {
    Version int `json:"version"`
    Value   int `json:"value"`
}

type Second struct {
    Version int `json:"version"`
    Value   int `json:"v"`
}

type MyStruct struct {
    Version  int `json:"version"`
    OldValue int `json:"value"`
    Value    int `json:"v"`
}

func main() {
    oldValue := []byte(`{"version":1, "value":5}`)
    newValue := []byte(`{"version":2, "v":7}`)

    var m MyStruct

    err := json.Unmarshal(newValue, &m)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("New Struct")
    fmt.Println(m.Value)

    err = json.Unmarshal(oldValue, &m)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Old Struct")
    if m.Version <= 1 {
        m.Value = m.OldValue
    }
    fmt.Println(m.Value)

}

最佳答案

编辑:您实际上可以通过一次解码来完成,尽管您需要另一种类型:

type Second struct {
    Version int `json:"version"`
    Value   int `json:"v"`
}

type SecondWithOldValue struct {
    OldValue int `json:"value"`
    Second
}

type MyStruct SecondWithOldValue

func (v *MyStruct) UnmarshalJSON(b []byte) error {
    if err := json.Unmarshal(b, (*SecondWithOldValue)(v)); err != nil {
        return err
    }

    if v.Version <= 1 {
        v.Value = v.OldValue
    }
    return nil
}

Playground :https://play.golang.org/p/yII-ncxnU4 .

下面是旧答案。


如果您对双重解码没问题,您可以这样做:

type Second struct {
    Version int `json:"version"`
    Value   int `json:"v"`
}

type MyStruct struct {
    Second
}

func (v *MyStruct) UnmarshalJSON(b []byte) error {
    if err := json.Unmarshal(b, &v.Second); err != nil {
        return err
    }

    if v.Version <= 1 {
        var oldV struct{ Value int }
        if err := json.Unmarshal(b, &oldV); err != nil {
            return err
        }
        v.Value = oldV.Value
    }
    return nil
}

首先,解码到内部结构中,检查版本,如果是旧版本,则获取旧值。

Playground :https://play.golang.org/p/AaULW6vJz_ .

关于json - 重命名的 JSON 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33236040/

相关文章:

javascript - 使用jquery从JSP响应中解析Json

go - 如何保持连接处于事件状态以使用 RabbitMQ streadway/amqp 发布消息?

memory - 为什么 `[0]byte` 在结构中的位置很重要?

php - 从 API 调用中提取的内容给出 0 值

mysql - JSON_ARRAY_APPEND() 如果目标值为空则拒绝 Mysql

java - 使用 Jayway 的可选 JsonPath

java - 如何向我的 JSON 映射器引入转义字符?

go - 如何在 Golang 中检测额外的 mime 类型

json - 阻止 gorm 在 where 子句中提示 Unknown column ‘users.deleted_at’

go - Gorm原子更新到增量计数器