我们想在生产中将 JSON 字段 value
重命名为 v
。在我们所有的用户都使用新结构之前,我们将继续将旧的 JSON 结构添加到我们的代码中。所以我们也想处理这个问题。
如果您注意到,First
是原始结构,Second
是新结构。为了处理这两种结构,我创建了一个 MyStruct
并基于 version
,我将 OldValue
复制到 Value
if m.Version <= 1 {
m.Value = m.OldValue
}
有没有更好的方法来处理这个问题,而不是我的代码。
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/