Idiomatic way to embed struct with custom MarshalJSON() method

前端 未结 5 583
星月不相逢
星月不相逢 2021-02-04 09:30

Given the following structs:

type Person {
    Name string `json:\"name\"`
}

type Employee {
    Person
    JobRole string `json:\"jobRole\"`
}
<
5条回答
  •  迷失自我
    2021-02-04 10:10

    I've used this approach on parent structs to keep the embedded struct from overriding marshaling:

    func (e Employee) MarshalJSON() ([]byte, error) {
      v := reflect.ValueOf(e)
    
      result := make(map[string]interface{})
    
      for i := 0; i < v.NumField(); i++ {
        fieldName := v.Type().Field(i).Name
        result[fieldName] = v.Field(i).Interface()
      }
    
      return json.Marshal(result)
    }
    

    It's handy but nests the embedded structs in the output::

    {"JobRole":"Sales","Person":{"name":"Bob"}}
    

    For a tiny struct like the one in the question, @Flimzy's answer is good but can be done more succinctly:

    func (e Employee) MarshalJSON() ([]byte, error) {
        return json.Marshal(map[string]interface{}{
            "jobRole": e.JobRole,
            "name":    e.Name,
        })
    }
    

提交回复
热议问题