du060334 2015-07-17 01:59
浏览 142
已采纳

Golang修改不带结构的JSON

type Struct struct {
   Value  string `json:"value"`
   Value1 string `json:"value_one"`
   Nest   Nested `json:"nest"`
}

type Nested struct {
   Something string `json:"something"`
}

I want to add elements which are not in the structs definitions without creating another struct type. For example

Struct.Extra1 = Nested{"yy"}
Struct.Nested.Extra2 = "zz"

Which will result

{
    "Value": "xx",
    "Value1": "xx",
    "Extra1": {
      "Something", "yy"
    },
    "Nest": {
      "Something": "xx",
      "Extra2": "zz"
    }
}

SOLUTION1: I thought of adding omitempty to achieve this but it makes the structs complex.

type Struct struct {
   Value  string
   Value1 string
   Nest   Nested
   Extra1 Nested `json:"omitempty"`
}

type Nested struct {
   Something string
   Extra2 string `json:"omitempty"`
}

SOLUTION2:

myextras := make(map[string]interface{})
// get Struct.Nested in map[string]interface{} format
myextras = Struct.Nest
myextras["Extra2"] = "zz"

// get Struct in map[string]interface{} format
struct["Nest"] = myextras
struct["Extra1"] = Nested{"yy"}

// solves the problem with lots of type casting but doesn't support json tag naming

Is there a better solution to add nested elements which are not represented in struct datatype with json-tag support and could be used to output to user.

  • 写回答

3条回答 默认 最新

  • dongma0722 2015-07-20 11:14
    关注

    Based on this answer: Can I use MarshalJSON to add arbitrary fields to a json encoding in golang?

    You could do something like (demo: http://play.golang.org/p/dDiTwxhoNn):

    package main
    
    import (
        "encoding/json"
        "fmt"
        "log"
    )
    
    type Book struct {
        Title  string
        Author string
    
        // extra is used for additional dynamic element marshalling
        extra func() interface{}
    }
    
    type FakeBook Book
    
    func (b *Book) SetExtra(fn func() interface{}) {
        b.extra = fn
    }
    
    func (b *Book) MarshalJSON() ([]byte, error) {
        if b.extra == nil {
            b.extra = func() interface{} { return *b }
        }
    
        return json.Marshal(b.extra())
    }
    
    func main() {
        ms := &Book{
            Title:  "Catch-22",
            Author: "Joseph Heller",
        }
    
        ms.SetExtra(func() interface{} {
            return struct {
                FakeBook
                Extra1 struct {
                    Something string `json:"something"`
                } `json:"extra1"`
            }{
                FakeBook: FakeBook(*ms),
                Extra1: struct {
                    Something string `json:"something"`
                }{
                    Something: "yy",
                },
            }
        })
    
        out, err := json.MarshalIndent(ms, "", "  ")
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Println(string(out))
    
        mb := &Book{
            Title:  "Vim-go",
            Author: "Fatih Arslan",
        }
    
        mb.SetExtra(func() interface{} {
            return struct {
                FakeBook
                Something string `json:"something"`
            }{
                FakeBook:  FakeBook(*mb),
                Something: "xx",
            }
        })
    
        out, err = json.MarshalIndent(mb, "", "  ")
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Println(string(out))
    
        mc := &Book{
            Title:  "Another-Title",
            Author: "Fatih Arslan",
        }
    
        out, err = json.MarshalIndent(mc, "", "  ")
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Println(string(out))
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作