go - 加载包含不同结构项目列表的 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
。有没有办法使这项工作?
谢谢!
解决方案
最后我采用了这种方法:
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
推荐阅读
- vue.js - VUE中如何将表单值转换为数组
- algorithm - 这个优化算法的正式名称?
- java - 使用数组列表在java中写入文件但不工作
- json - 使用 jq 从 json 获取父值
- android - 在 AndroidStudio 3.1.4 中,CoordinatorLayout 不显示 targetSdkVersion 28
- r - 在 R 中重塑 data.frame
- reactjs - 允许在 npm 模块中直接导入文件,如 lodash
- python - python服务器完成但没有监听
- talend - Talend - 无法从 tsendmail 发送邮件
- google-apps-script - 将谷歌表格中的单元格设置为只读而不锁定其列宽?