【问题标题】:In Go is there a way to convert map of structure to slice of structure在 Go 中有没有办法将结构映射转换为结构切片
【发布时间】:2020-01-25 17:52:58
【问题描述】:

我必须将结构映射转换为 Golang 中的结构切片,即下面指定的源结构到目标结构。

// Source
var source map[string]Category

type Category struct {
    A           int
    SubCategory map[string]SubCategory
}

type SubCategory struct {
    B int
    C string
}

// Target
var target []OldCategory

type OldCategory struct {
    OldA           int `mapstructure:"A"`
    OldSubCategory []OldSubCategory
}

type OldSubCategory struct {
    OldB int    `mapstructure:"B"`
    OldC string `mapstructure:"C"`
}

我指的是地图结构包(“github.com/mitchellh/mapstructure”)。 从源转换为目标的一种方法是在源实例中迭代所有子类别,然后是类别,并使用 mapstructure.Decode() 单独转换每一个。

有没有使用mapstrucuture包的直接方法,其中我使用NewDecoder和DecoderConfig.DecodeHook创建一个自定义解码器钩子,每当我遇到源作为结构的映射和目标作为结构的切片时,我在DecodeHookFunc中处理它函数。

mapstructure的相关文档 https://godoc.org/github.com/mitchellh/mapstructure#NewDecoder

【问题讨论】:

    标签: go struct go-map


    【解决方案1】:

    您可以使用 mapstructure 解码器挂钩,在解码器挂钩内编写自定义逻辑来完成您的工作。但是没有标准的 lib 函数来完成你的工作。

    例子:

    dc := &mapstructure.DecoderConfig{Result: target, DecodeHook: customHook}
        ms, err := mapstructure.NewDecoder(dc)
        if err != nil {
            return err
        }
    
        err = ms.Decode(source)
        if err != nil {
            return err
        }
    
    func customHook(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
    if f.Kind() == reflect.Int && t.Kind() == reflect.Bool {
        var result bool
        if data == 1 {
            result = true
        }
        return result, nil
    
    }
    

    因此,只要具有您的自定义逻辑,您就可以使用自定义挂钩从技术上将任何内容解码为任何内容。

    【讨论】:

    • 它工作,我将customHook中的data interface{}转换为[]Category,当遇到```map[string]Category```和```[]SubCategory```遇到` ``map[string]SubCategory``` 并从 customHook 函数返回这些切片。解码器接收切片输入并能够将其映射到目标切片,分别为target []OldCategoryOldSubCategory []OldSubCategory
    【解决方案2】:

    使用嵌套的 for 循环:

    for _, c := range source {
        oc := OldCategory{OldA: c.A}
        for _, sc := range c.SubCategory {
            oc.OldSubCategory = append(oc.OldSubCategory, OldSubCategory{OldB: sc.B, OldC: sc.C})
        }
        target = append(target, oc)
    }
    

    【讨论】:

    • 这似乎是我建议的迭代方法。问题是,每个类别和子类别中有 10-15 个字段。我想创建一个通用解决方案,以便它易于扩展。因此,如果将来有结构更改,我只想更新存储结构的模型文件,而不是查看代码逻辑。
    【解决方案3】:

    在 Go 中有没有办法将结构映射转换为结构切片

    不,没有语言结构或语法糖。

    【讨论】:

      猜你喜欢
      • 2020-09-12
      • 2017-02-19
      • 1970-01-01
      • 2020-08-16
      • 2016-07-30
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多