Go语言 如何创建动态结构体,除了使用接口和使用spread运算符

ngynwnxp  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(335)

我正在尝试用Go和Fiber框架创建新的API。我正在使用MongoDB。请参考我的以下结构

type Product struct {
    Name           string              `json:"name"`
    Code           string              `json:"code"`
    Description    string              `json:"description"`
    Brand          string              `json:"brand"`
    Variants       []map[string]string `json:"variants"`
    Categories     []int               `json:"categories"`
}

Variants字段将有另一个对象数组,但是字段是动态的,所以我不能定义结构,现在我用[]map[string][string]解决了这个问题。
我的任务在这里我必须形成CSV文件与下面的格式。

[{
    Name: "Rock",
    Code: "RRR"
    Description: "This is rock"
    Brand: "R"
    ...variants
},
{
    Name: "Rock",
    Code: "RRR"
    Description: "This is rock"
    Brand: "R"
    ...variants
},
{
    Name: "Rambo",
    Code: "RAM"
    Description: "This is Rambo"
    Brand: "RA"
    ...variants
},
{
    Name: "Rambo",
    Code: "RAM"
    Description: "This is Rambo"
    Brand: "RA"
    ...variants
}]

每一行只有变量会改变。其他的将保持不变。我形成了其他字段,除了变量。我不能创建结构,因为数据将是动态的。
我有很多困惑
1.如何创建动态字段的结构
1.如何在根级别传播变体
我来自javascript。所以,我们使用了spread操作符。在这里我对如何在Golang中做到这一点感到困惑。
帮帮我伙计们

bvn4nwqk

bvn4nwqk1#

@mkopriva是对的
但是,如果愿意,可以使用反射动态构造新的结构
下面是一个示例:

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

type DynamicMap map[string]interface{}

type Product struct {
    Name        string            `json:"name"`
    Code        string            `json:"code"`
    Description string            `json:"description"`
    Brand       string            `json:"brand"`
    Variants    map[string]string `json:"variants"`
    Categories  []int             `json:"categories"`
}

func (j Product) MarshalJSON() ([]byte, error) {
    m := DynamicMap{}
    t := reflect.TypeOf(j)
    v := reflect.ValueOf(j)
    for i := 0; i < t.NumField(); i++ {
        if t.Field(i).Tag.Get("json") == "variants" {
            dyn := v.Field(i).Interface().(map[string]string)
            for key, val := range dyn {
                m[key] = val
            }
        } else if t.Field(i).Type.Kind() == reflect.String {
            m[t.Field(i).Tag.Get("json")] = v.Field(i).String()
        } else {
            m[t.Field(i).Tag.Get("json")] = v.Field(i)
        }

    }
    return json.Marshal(m)
}

func (j Product) UnmarshalJSON(data []byte) error {
    fmt.Println("Unmarshal...")
    return json.Unmarshal(data, &j)
}

func main() {
    p := Product{Name: "aa", Variants: map[string]string{"a": "a", "b": "b"}}
    marshal, err := json.Marshal(p)
    if err != nil {
        fmt.Printf("%v\n", err)
    }
    fmt.Printf("%s\n", marshal)
}

{"a":"a","b":"b","brand":"","categories":{},"code":"","description":"","name":"aa"}

相关问题