Let's say I have the following yaml file:
key1:
- "Value1"
- "Value2"
key2:
- "Value3"
- "Value4"
And I want to unmarshal that in Go. I can let Go decide what the scheme should look like and print it out.
m := make(map[interface{}]interface{})
err := yaml.Unmarshal(yaml_file, &m)
fmt.Prinf(m)
This will print something like this:
map[key1:[Value1 Value2] key2:[Value3 Value4]]
But maps are unordered. The order is very important for me tho and I also don't want to loose the keys.
I can't just create a struct and try to unmarshal the yaml file to a slice of that struct...
type Element struct {
Key string
Value interface{}
}
t := []Element{}
err := yaml.Unmarshal(yaml_file, &t)
if err != nil {
log.Fatalf("error: %v", err)
}
Will print error: yaml: unmarshal errors: line 2: cannot unmarshal !!map into []Element
There is no field tag to tell the yaml parser to fill the Key property with the yaml key.
Is there a different way than writing my own decoder?
Just found the answer right before I wanted to post the question.
The answer is MapSlice!
You need to import yaml.v2 from gopkg. (As of writing this MapSlices don't seem to be implemented in yaml.v3 yet)
MapSlices implement exactly what I needed and are made of a number of MapItems.
type MapItem struct {
Key, Value interface{}
}
So now just unmarshal to a MapSlice. If you want to work with your own types you can always convert it but might need to do some typecasting.
m := yaml.MapSlice{}
yaml.Unmarshal(yaml_file, &m)
t := []Element{}
for _, item := range m {
t = append(t, Element{item.Key.(string), item.Value})
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With