在 Golang 中编组结构时可以跳过 json 标记吗?

Posted

技术标签:

【中文标题】在 Golang 中编组结构时可以跳过 json 标记吗?【英文标题】:Can I skip a json tag while Marshalling a struct in Golang? 【发布时间】:2021-12-24 13:04:39 【问题描述】:

我有一个场景,我想在 Golang 中编组一个结构时跳过一个 json 标记。那可能吗?如果是这样,我该如何实现?

例如,我得到这个 json: "Employee":"Interface":"Name":"xyz", "Address":"abc"

但我希望 json 是: "Employee":"Name":"xyz", "Address":"abc"

【问题讨论】:

Employee:Interface:Name:"xyz", Address:"abc" 不是 JSON,其他也不是。这看起来像 fmt.Printf("%+v", e) 的输出,这与 JSON 不同。您应该更清楚您需要帮助的内容。 你说得对,我现在已经编辑了我的问题。 【参考方案1】:

您可以使用匿名结构

type Employee struct 
    Interface Interface

type Interface struct 
    Name string
    Address string

func main() 
    a := EmployeeInterface: InterfaceName: "xyz", Address: "abc"
    b := struct 
        Employee Interface
    
        Employee: a.Interface,
    
    jsonResult, _ := json.Marshal(b)
    fmt.Println(string(jsonResult)) // "Employee":"Name":"xyz","Address":"abc"


【讨论】:

【参考方案2】:

如果 Interface 字段的类型 不是 实际接口而是结构类型,那么您可以嵌入该字段,这会将嵌入的结构字段提升为 Employee 并将其编组到 JSON 中得到你想要的输出。

type Employee struct 
    Interface // embedded field


type Interface struct 
    Name    string
    Address string


func main() 
    type Output struct Employee Employee 

    e := EmployeeInterface: InterfaceName: "xyz", Address: "abc"
    out, err := json.Marshal(Outpute)
    if err != nil 
        panic(err)
    
    fmt.Println(string(out))

https://play.golang.org/p/s5SFfDzVwPN


如果Interface 字段的类型 一个实际的接口类型,那么嵌入将无济于事,相反,您可以让Employee 类型实现json.Marshaler 接口并自定义生成的JSON。

例如,您可以执行以下操作:

type Employee struct 
    Interface Interface `json:"-"`


func (e Employee) MarshalJSON() ([]byte, error) 
    type E Employee
    obj1, err := json.Marshal(E(e))
    if err != nil 
        return nil, err
    

    obj2, err := json.Marshal(e.Interface)
    if err != nil 
        return nil, err
    

    // join the two objects by dropping '' from obj1 and
    // dropping '' from obj2 and then appending obj2 to obj1
    //
    // NOTE: if the Interface field was nil, or it contained a type
    // other than a struct or a map or a pointer to those, then this
    // will produce invalid JSON and marshal will fail with an error.
    // If you expect those cases to occur in your program you should
    // add some logic here to handle them.
    return append(obj1[:len(obj1)-1], obj2[1:]...), nil

https://play.golang.org/p/XsWZfDSiFRI

【讨论】:

感谢您的回复,您提供的第二个解决方案对我有用。

以上是关于在 Golang 中编组结构时可以跳过 json 标记吗?的主要内容,如果未能解决你的问题,请参考以下文章

是否有一个包可以在 golang 中编组进出 x-www-form-urlencoding

golang 将json映射到GO中的struct,用于直接编组,unmarshal

在Python中使用Golang方法时内存不足

在 Golang 中解组 XML 时如何在 interface 中获取数据?

解组忽略空字段

是否可以在包含地图名称的同时编组一个 go 结构?