Golang在接口映射上迭代



我正在尝试迭代golang中的接口映射,它具有以下结构,我可以使用for循环迭代到单个级别,但无法深入获取接口的值。

Yaml

steps:
execute:
- mvn : 1.9.3
goals: 'clean install'
concurrent: false
- mvn : 1.9.3
goals: 'dependency-check:check'
concurrent: false

转到

// reading a yaml file 
// trying to use "gopkg.in/yaml.v2" package
data, err := ioutil.ReadFile(fileName)
m := make(map[interface{}]interface{})
err = yaml.Unmarshal([]byte(data), &m)
for k, v := range m {
// Trying to explore the data here
fmt.Println("k:", k, "v:", v)
}

输出

fmt.Printf("--- m:n%vnn", m)

看起来像低于

map[steps:map[execute:[map[concurrent:false goals:clean install mvn:1.9.3] map[concurrent:false goals:dependency-check:check mvn:1.9.3]]]]

我的尝试

for k, v := range m {
fmt.Println("k:", k, "v:", v)
}

假设您有一个map[interface{}]interface{}和[]interface{}的树,使用以下代码遍历树:

func walk(v interface{}) {
switch v := v.(type) {
case []interface{}:
for i, v := range v {
fmt.Println("index:", i)
walk(v)
}
case map[interface{}]interface{}:
for k, v := range v {
fmt.Println("key:", k)
walk(v)
}
default:
fmt.Println(v)
}
}

此代码向下递归结构,并使用类型开关来查找切片和映射。

这样使用:

data, err := ioutil.ReadFile(fileName)
var m map[interface{}]interface{}
err = yaml.Unmarshal([]byte(data), &m)
walk(m)

在操场上运行

要访问Execute对象并对其进行迭代,您必须执行许多类型断言,如@vooker给出的答案。

实际上,不建议使用map[interface{}]interface{}进行解组处理。它应该被分解为一个作为结构的具体类型。

从YAML结构中,它可以被翻译成这样的结构类型:


type data struct {
Steps struct {
Execute []execute `yaml:"execute"`
} `yaml:"steps"`
}
type execute struct {
MVN        string `yaml:"mvn"`
Goals      string `yaml:"goals"`
Concurrent bool   `yaml:"concurrent"`
}

从结构上看,更容易从YAML访问未分组的数据。例如,如果您想对";执行";对象你可以这样做:

var result data
yaml.Unmarshal([]byte(str), &result)
fmt.Println(result) 
// iterate over the slice of object
for _, e := range result.Steps.Execute {
fmt.Println()
fmt.Println("mvn:", e.MVN)
fmt.Println("goals:", e.Goals)
fmt.Println("concurrent:", e.Concurrent)
}

在操场上试试

我不知道你说的是什么意思"m〃的值;因为这看起来不像我在Go中看到的任何格式,所以我将讨论一些情况:当接口可能是类型时,你知道它们是什么,而当接口可以是任何东西时,你不确定。

如果你只知道有几个类型进入了映射,你可以进行类型切换,并单独处理每个类型。这将使您有机会引用子字段并打印它们。如果你总是为相同类型的对象打印相同的信息,你可以考虑在结构中添加一个String() string函数,这将使它们实现Stringer接口,然后你可以打印对象,即使它被装箱为接口,你的String((函数也会被调用。

如果你使用的是一个正在填充映射的库,或者映射中的类型多样性太大,类型切换不合理,那么你要么想要一个通用的解决方案,比如类似库的喷涌,要么需要一个用反射编写的自定义解决方案。

相关内容

  • 没有找到相关文章

最新更新