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

我有一个格式如下的 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 Actions


func 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。有没有办法使这项工作?


呼如林
浏览 144回答 2
2回答

慕哥6287543

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

扬帆大鱼

最后我采用了这种方法:    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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go