Why is the unmarshaled YAML data empty?

Viewed 192

I have a problem unmarshaling a simple slice of YAML data:

package main

import (
    "fmt"

    "gopkg.in/yaml.v2"
)

type myDataStruct struct {
    HTTP []struct {
        Name   string
        Target string
    }
}

func main() {
    yamlData := `
HTTP:
  - name: one
    target: http://wazaa
  - name: two
    target: http://wazii
`
    var myData myDataStruct
    err := yaml.Unmarshal([]byte(yamlData), &myData)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Print(myData)
}

Playground: https://play.golang.org/p/Srb2DJVVZqN

The result is {[]} and my limited knowledge of Go does not help to understand why?

1 Answers

If you don't specify the mapping between labels used in the YAML source and Go struct fields, by default they will only be matched if only changing the first letter to lower matches.

E.g. the struct field Name will match name, but not NAME.

Specify the mapping for the HTTP field:

type myDataStruct struct {
    HTTP []struct {
        Name   string
        Target string
    } `yaml:"HTTP"`
}

With this change it works and outputs (try it on the Go Playground):

{[{one http://wazaa} {two http://wazii}]}

It's good practice to provide mappings for all fields, so it'll continue to work if you rename the fields:

type myDataStruct struct {
    HTTP []struct {
        Name   string `yaml:"name"`
        Target string `yaml:"target"`
    } `yaml:"HTTP"`
}

Although in your case the default matching works for the Name and Target fields without providing the mappings.

Related