为了账号安全,请及时绑定邮箱和手机立即绑定

加载包含不同结构项目列表的 YAML 文件

加载包含不同结构项目列表的 YAML 文件

Go
呼如林 2022-06-27 17:18:52
我有一个格式如下的 YAML:actions:  - type: one    onekey: value  - type: two    twokey: value    foo: bar我想将它加载到 Go 结构中。我尝试使用mapstructurs它,DecodeHook但我无法让它工作。这是我尝试过的:type Actions struct {    actions []Action}type Action interface {}type One struct {    Onekey string}type Two struct {    Twokey string    Foo    string}var actions Actionsfunc Load() {...    config := &mapstructure.DecoderConfig{        DecodeHook: func(sourceType, destType reflect.Type, raw interface{}) (interface{}, error) {            if fmt.Sprintf("%s", destType) == "Action" {                var result Action                switch raw.(map[string]interface{})["type"] {                case "one":                    result = One{}                case "two":                    result = Two{}                }                mapstructure.Decode(raw, &result)                return result, nil            }            return raw, nil        },        Result: &actions,    }...}这很丑陋,也不起作用。我得到:panic: interface conversion: interface {} is map[interface {}]interface {}, not map[string]interface {}首先有:if fmt.Sprintf("%s", destType) == "Action"这是可怕的,但我让这部分工作的唯一方法。然后是读取列表项并通过键将其转换为正确的结构type。有没有办法使这项工作?
查看完整描述

2 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

看看 viper 包:https ://github.com/spf13/viper 它可以让你从 toml、json yaml 等文件中读取,然后你可以将每个配置值传递给你的结构。



查看完整回答
反对 回复 2022-06-27
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

最后我采用了这种方法:


    config := &mapstructure.DecoderConfig{

        DecodeHook: func(sourceType, destType reflect.Type, raw interface{}) (interface{}, error) {

            var result Action

            if fmt.Sprintf("%s", destType) == "Action" {

                rawMap := raw.(map[interface{}]interface{})

                switch rawMap["type"] {

                case "one":

                    result = One{}

                case "two":

                    result = Two{}

                }


                mapstructure.Decode(raw, &result)

                return result, nil

            }

            return raw, nil

        },

        Result: &actions,

    }

我只是从 Go 开始,所以可能有更好的方法,但这有点解决了我遇到的两个问题。


更正:我不得不恢复if fmt.Sprintf("%s", destType) == "Action"到reflect.TypeOf(result) == nil


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号