如何将具有嵌入式结构的结构展平为 json

给定以下结构类型,StructA并且StructB嵌入在CompleteStruct


type StructA struct {

    A int `json:"a_a"`

    B int `json:"a_b"`

    C int `json:"a_c"`

}

type StructB struct {

    A int `json:"b_a"`

    B int `json:"b_b"`

}


type CompleteStruct struct {

    Name string `json:"name"`

    StructA

    StructB

}


这s是一个新结构。


s := CompleteStruct{Name: "Example",

    StructA: StructA{

        A: 1, 

        B: 2, 

        C: 3,

    },

    StructB: StructB{

        A: 4,

        B: 5,

    },

}

你如何转化s为下面的json。


[

  {

    "name": "Example",

    "field": "a_a",

    "value": 1

  },

  {

    "name": "Example",

    "field": "a_b",

    "value": 2

  },

  {

    "name": "Example",

    "field": "a_c",

    "value": 3

  },

  {

    "name": "Example",

    "field": "b_a",

    "value": 4

  },

  {

    "name": "Example",

    "field": "b_b",

    "value": 5

  }

]

注意:实际上,CompleteStruct将包含 10 个或更多嵌入式结构,每个嵌入式结构将包含 10 个或更多字段。所以我想要一个不需要单独输入每个字段的解决方案,我认为这将需要使用反射


萧十郎
浏览 105回答 2
2回答

慕哥9229398

不反思是解决不了的。简单示例:func (u *CompleteStruct) MarshalJSON() ([]byte, error) {&nbsp; &nbsp; type Result struct {&nbsp; &nbsp; &nbsp; &nbsp; Name&nbsp; string `json:"name"`&nbsp; &nbsp; &nbsp; &nbsp; Field string `json:"field"`&nbsp; &nbsp; &nbsp; &nbsp; Value any&nbsp; &nbsp; `json:"value"`&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; var res []Result&nbsp; &nbsp; val := reflect.ValueOf(u).Elem()&nbsp; &nbsp; for i := 0; i < val.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; field := val.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; switch field.Kind() {&nbsp; &nbsp; &nbsp; &nbsp; case reflect.Struct:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < field.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tp := field.Type().Field(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; field := field.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = append(res, Result{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name:&nbsp; u.Name,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Field: tp.Tag.Get("json"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Value: field.Interface(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return json.Marshal(res)}

烙印99

这应该给你你想要的结构:package mainimport (&nbsp; &nbsp; "encoding/json"&nbsp; &nbsp; "os"&nbsp; &nbsp; "reflect")type StructA struct {&nbsp; &nbsp; A int `json:"a_a"`&nbsp; &nbsp; B int `json:"a_b"`&nbsp; &nbsp; C int `json:"a_c"`}type StructB struct {&nbsp; &nbsp; A int `json:"b_a"`&nbsp; &nbsp; B int `json:"b_b"`}type CompleteStruct struct {&nbsp; &nbsp; Name string `json:"name"`&nbsp; &nbsp; StructA&nbsp; &nbsp; StructB}func main() {&nbsp; &nbsp; s := CompleteStruct{Name: "Example",&nbsp; &nbsp; &nbsp; &nbsp; StructA: StructA{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; A: 1,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; B: 2,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; C: 3,&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; StructB: StructB{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; A: 4,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; B: 5,&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; }&nbsp; &nbsp; flat(s)&nbsp; &nbsp; json.NewEncoder(os.Stdout).Encode(results)}type resp struct {&nbsp; &nbsp; Name&nbsp; string `json:"name"`&nbsp; &nbsp; Field string `json:"field"`&nbsp; &nbsp; Value any&nbsp; &nbsp; `json:"value"`}var globalName stringvar results []respfunc flat(s interface{}) {&nbsp; &nbsp; st := reflect.TypeOf(s)&nbsp; &nbsp; for i := 0; i < st.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; field := st.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; if field.Type.Kind() == reflect.Struct {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; flat(reflect.ValueOf(s).Field(i).Interface())&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name := field.Tag.Get("json")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if name == "name" {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; globalName = reflect.ValueOf(s).Field(i).String()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results = append(results, resp{Name: globalName, Field: name, Value: reflect.ValueOf(s).Field(i).Interface()})&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}go run ./main.go | jq '.'
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go