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

Can I skip a json tag while Marshalling a struct in Golang?

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

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

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

您可以使用匿名结构

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

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

type Employee struct {
    Interface // embedded field
}

type Interface struct {
    Name    string
    Address string
}

func main() {
    type Output struct{ Employee Employee }

    e := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
    out, err := json.Marshal(Output{e})
    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