在 []struct 中追加不需要的类型

我正在学习去和卡住的结构


我需要生成json:


{

    "and" : [

        { "term" : { "name.second" : "ba" } }

      ]

    }

  }

所以我可以用代码做到这一点:


package main


import (

  "encoding/json"

  "fmt"

)


type Term map[string]interface{}


type TermHash struct {

  Term `json:"term"`

}


type Filter struct {

        And []TermHash `json:"and"`

}


func main() {

  var filter Filter

  filter.And = append(filter.And, TermHash{ Term{"name.second" : "ba"}})

  jsonFilter, _ := json.MarshalIndent(filter, "", "   ")

  fmt.Printf(string(jsonFilter))

}

但我真的不想使用单独的 TermHash 和 Term 类型,它在代码中似乎没有必要,仅用于添加此行进行过滤。我可以避免使用它吗?


我只想用类型过滤器来完成这个:


type Filter struct {

  And []struct{

    Term map[string]interface{} `json:"term"`

  } `json:"and"`

}

这看起来更具可读性并代表预期的结果,但我无法以这种方式创建 Term 的实例。有没有办法在不创建单独类型的情况下向 json 添加条款行?


森林海
浏览 134回答 2
2回答

牧羊人nacy

您真正想要的是 JSON 编码的自定义方式Term。它不是一个简单的地图,而是像一个包含地图的对象一样进行编组。所以,让我们MarshalJSON为它编写这个习惯:type Term map[string]interface{}func (t Term) MarshalJSON() ([]byte, error) {    return json.Marshal(struct {        T map[string]interface{} `json:"term"`    }{t})}我们struct在这里创建一个匿名的,用我们自己填充,然后将其编组为 JSON。注意map[string]interface{}这里的使用。虽然看起来像Term,但它实际上是一种不同的类型,具有自己的 JSON 编码方式。如果您尝试在此处保存一些输入并使用T Term,您会发现自己处于无限循环中。(创建与其他类型具有相同结构的新类型的想法是 Go 的主要部分。)现在我们的数据结构很简单;只是一部分术语:type Filter struct {    And []Term `json:"and"`}func main() {    var filter Filter    filter.And = append(filter.And, Term{"name.second" : "ba"})    jsonFilter, _ := json.MarshalIndent(filter, "", "   ")    fmt.Printf(string(jsonFilter))}也就是说,您也可以走另一条路,让您的数据模型与 JSON 更紧密地匹配。在那种情况下Term应该是一个结构,而不是一个地图。你可能会这样写:type Term struct {    Values map[string]interface{} `json:"term"`}func NewTerm(key, value string) Term {    return Term{map[string]interface{}{key: value}}}type Filter struct {    And []Term `json:"and"`}func main() {    var filter Filter    filter.And = append(filter.And, NewTerm("name.second", "ba"))    jsonFilter, _ := json.MarshalIndent(filter, "", "   ")    fmt.Printf(string(jsonFilter))}

SMILET

您可以围绕它创建一个包装函数。package mainimport (    "fmt"    "encoding/json")type Filter struct {        And    []map[string]interface{}  `json:"and"`}func WrapFilter(i interface{}) Filter {    return Filter{        And: []map[string]interface{}{            map[string]interface{}{                "term": i,            },        },    }}func main() {    f := WrapFilter(map[string]string{"name.second": "ba"})     json.Marshal(f) }这样,您将始终"term"在编组的 JSON 中拥有二级密钥。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go