YAML in Go: Difference between revisions
Jump to navigation
Jump to search
Line 96: | Line 96: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=Behavior when an Entire Subtree Is Missing= | =Behavior when an Entire Subtree Is Missing= | ||
[[Go_Structs#struct_Zero_Value]] |
Revision as of 18:07, 5 January 2024
Internal
Overview
Declare a recursive structure that matches the structure of the YAML file, and then use a YAML encoder/decoder to marshall/unmarshall data in and out.
YAML support is available in the gopkg.in/yaml.v3
package.
If the structure fields are not capitalized, they are not visible across packages, and their content will zero-ed. The structure field will be accessible, but its content will be the corresponding zero value for the type.
Come up with an in-depth explanation for this.
package main
import (
"fmt"
"gopkg.in/yaml.v3"
"os"
)
//
// color: "blue:
// details:
// size: 10
// weight 2.2
// used: true
// options:
// - light
// - medium
// - heavy
//
// Note: if the package name is "config", name the structure differently, config.Config does not work well
type Config struct {
Color string `yaml:"color"`
Details Details `yaml:"details"`
}
type Details struct {
Size int `yaml:"size"`
Weight float64 `yaml:"weight"`
Used bool `yaml:"used"`
Options []string `yaml:"options"`
}
func main() {
config := Config{
Color: "blue",
Details: Details{
Size: 10,
Weight: 2.2,
Used: true,
Options: []string{"light", "medium", "heavy"},
},
}
f, err := os.Create("/Users/ovidiu/tmp/test.yaml")
if err != nil { ... }
//
// Marshal recursive memory struct into a file
//
if err := yaml.NewEncoder(f).Encode(&config); err != nil { ... }
if err = f.Close(); err != nil { ... }
fmt.Printf("yaml file written and closed\n")
f, err = os.Open("/Users/ovidiu/tmp/test.yaml")
if err != nil { ... }
defer func() {
if err = f.Close(); err != nil { ... }
}()
//
// Unmarshall the file into a different memory struct
//
config2 := Config{}
err = yaml.NewDecoder(f).Decode(&config2)
// the decoder return io.EOF on an empty YAML file, even if the file contains
// comments. We don't want to handle this as error, but as simply "empty file"
if errors.Is(err, io.EOF) {
// nothing to do, the config is empty anyway
log.Printf("empty configuration\n")
} else {
// handle as error
...
}
fmt.Printf("%+v\n", config2)
}