2017-08-07 8 views
1

私は動的なスキーマを持つYAML構造を持っています。明確な型を宣言するべきである、構造体に行く動的なスキーマのGolangとyaml

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

GoyamlマップYAML:私は、次のYAMLを持つことができます。ここでは、valは、signle番号か、配列か、またはマップである。

この状況に最適な解決法はどれですか?

+2

あなたは 'val'の型として' interface {} 'を試しましたか? – 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

答えを完璧にするには、 'int'、' [] int'、 '[] string'などの変数に' interface {} '型の' Val'をキャストする方法の行を追加できますか? – TehSphinX

+0

** **はswitch文の中に**キャストされています。それぞれのケースの中で 'val'は実際には正しいタイプです。 – RayfenWindspear

+0

ありがとう!私はそれを知らなかった。 +1私から – TehSphinX

関連する問題