猿问

在 Go 中的嵌入式结构中组合任意 JSON 对象

我正在尝试以{{"s":"v1", "t":"v2"}, {"s":"v3", "t":"v4"}, etc}Go 中的嵌入式结构的形式生成 JSON 对象。

当提前知道所有Problem项目时,一切都很好type Problems []Problem,如ONE()下面的func和Playground demo此处所示。

但是,如果某些 K:V 对包含空值,我想避免获取{{a},{},{c}}而不是所需的{{a},{c}},如TWO()下面的func和演示中所示。

或者,我如何probs := Problems{prob0, prob1, prob2, etc}在不提前知道是否会添加或省略问题项目的情况下随意组合?

package main


import (

    "encoding/json"

    "fmt"

)


type Problem struct {

     S string `json:"s,omitempty"`

     T string `json:"t,omitempty"`

}


 type Problems []Problem


 func main() {

     ONE()

     TWO()

}


 func ONE() {

     prob0 := Problem{S: "s0", T: "t0"}

     prob1 := Problem{S: "s1", T: "t1"}

     prob2 := Problem{S: "s2", T: "t2"}


     probs := Problems{prob0, prob1, probe}


       // fmt.Println(probs) // CORRECT: [{s0 t0} {s1 t1} {s2 t2}]


     b, _ := json.Marshal(probs)

     fmt.Println(string(b))


       // CORRECT: [{"s":"s0","t":"t0"},{"s":"s1","t":"t1"},{"s":"s2","t":"t2"}]``

}


 func TWO() {

     prob0 := Problem{S: "s0", T: "t0"}

     prob1 := Problem{S: "", T: ""} // empty values omited BUT NOT {}

     prob2 := Problem{S: "s2", T: "t2"}


     probs := Problems{prob0, prob1, probe}


       // fmt.Println(probs)

       // GOT:    [{s0 t0} { } {s2 t2}]

       // WANTED: [{s0 t0} {s2 t2}]


     b, _ := json.Marshal(probs)

     fmt.Println(string(b))


       // GOT:    [{"s":"s0","t":"t0"},{},{"s":"s2","t":"t2"}]

       // WANTED: [{"s":"s0","t":"t0"},{"s":"s2","t":"t2"}]

}


蛊毒传说
浏览 258回答 3
3回答

HUX布斯

一旦您将一个元素添加到您编组的数组/切片中,您就无能为力了。如果元素在数组/切片中,它将被编组(将包含在 JSON 输出中)。该json.Marshal()函数如何猜测您不想编组的元素?它不能。您必须排除不会出现在输出中的元素。在您的情况下,您要排除空Problem结构。最好/最简单的是创建一个辅助函数,[]Problem为您创建切片,排除空结构:func createProbs(ps ...Problem) []Problem {    // Remove empty Problem structs:    empty := Problem{}    for i := len(ps) - 1; i >= 0; i-- {        if ps[i] == empty {            ps = append(ps[:i], ps[i+1:]...)        }    }    return ps}使用它创建一个切片是这样的:probs := createProbs(prob0, prob1, prob2)在Go Playground上尝试修改后的应用程序。修改后的代码的输出(注意缺少空结构):[{"s":"s0","t":"t0"},{"s":"s1","t":"t1"},{"s":"s2","t":"t2"}][{"s":"s0","t":"t0"},{"s":"s2","t":"t2"}]

慕仙森

你不能轻易做到这一点。空结构也是一个结构,它将被序列化为{}. 甚至nil值将被序列化为null.以下代码:包主import (    "encoding/json"    "fmt")func main() {     xs := []interface{}{struct{}{},nil}     b, _ := json.Marshal(xs)     fmt.Println(string(b))}将产生:[{},null]Playground解决方案是为类型实现json.Marshaller接口Problems以跳过空结构。
随时随地看视频慕课网APP

相关分类

Go
我要回答