2017-08-07 53 views
1

我有一个具有动态模式的YAML结构,例如我可以有以下yaml:具有动态模式的Golang和yaml

array: 
    - name: myvar 
    val: 1 
    - name: mymap 
    val: [ 1, 2] 

Goyaml将yaml映射到Go结构,它应该声明明确的类型。在这里,val是一个数字,或者一个数组,甚至是一个地图。

这是最适合这种情况的解决方案吗?

+2

您是否尝试'interface {}'作为'val'的类型? – TehSphinX

+1

具体而言,您可以使用'interface {}'作为类型,然后使用类型切换(https://tour.golang.org/methods/16)来使用它。 – RayfenWindspear

+0

@RayfenWindspear,TehSphinX谢谢,这种方法没有任何缺点吗? –

回答

3

我决定添加一个显示类型断言的答案,而不是reflect包。您可以决定哪个最适合您的应用程序。我个人比较喜欢reflect包的复杂内置函数。

var data = ` 
array: 
    - name: myvar 
    val: 1 
    - name: mymap 
    val: [1, 2] 
` 

type Data struct { 
    Array []struct { 
     Name string 
     Val interface{} 
    } 
} 

func main() { 
    d := Data{} 
    err := yaml.Unmarshal([]byte(data), &d) 
    if err != nil { 
     log.Fatal(err) 
    } 

    for i := range d.Array { 
     switch val := d.Array[i].(type) { 
     case int: 
      fmt.Println(val) // is integer 
     case []int: 
      fmt.Println(val) // is []int 
     case []string: 
      fmt.Println(val) // is []string 
      // .... you get the idea 
     default: 
      log.Fatalf("Type unaccounted for: %+v\n", d.Array[i]) 
     } 
    } 

} 
+0

为了让你的答案完美,你可以添加如何将'interface'类型'Val'转换为'int','[] int','[] string'等类型的变量? – TehSphinX

+0

它们**在转换语句中被转换。在他们各自的情况下'val'实际上是正确的类型。 – RayfenWindspear

+0

谢谢!我没有意识到这一点。我的+1 – TehSphinX