ZetCode

Go YAML

最后修改时间 2024 年 4 月 11 日

在本文中,我们将展示如何在 Go 中使用 YAML。我们使用 yaml.v3 包。

YAML 格式

YAML (YAML Ain't Markup Language) 是一种人类可读的数据序列化语言。它通常用于配置文件,但也用于数据存储(例如调试输出)或传输(例如文档头)。

YAML 原生支持三种基本数据类型:标量(如字符串、整数和浮点数)、列表和关联数组。

YAML 文件的官方推荐文件名扩展名为 .yaml

yaml 包

yaml 包使 Go 程序能够轻松地对 YAML 值进行编码和解码。yaml 包支持 YAML 1.1 和 1.2 的大部分内容。

$ go get gopkg.in/yaml.v3

此命令安装 yaml 包的第 3 版。

Go YAML 读取示例

在第一个示例中,我们读取一个简单的 YAML 文件。

items.yaml
raincoat: 1
coins: 5
books: 23
spectacles: 2
chairs: 12
pens: 6

我们有一些标量值。

func Unmarshal(in []byte, out interface{}) (err error)

Unmarshal 函数解码字节切片中找到的第一个文档,并将解码后的值赋给 out 值。

read_items.go
package main

import (
     "fmt"
     "io/ioutil"
     "log"

     "gopkg.in/yaml.v3"
)

func main() {

     yfile, err := ioutil.ReadFile("items.yaml")

     if err != nil {

          log.Fatal(err)
     }

     data := make(map[interface{}]interface{})

     err2 := yaml.Unmarshal(yfile, &data)

     if err2 != nil {

          log.Fatal(err2)
     }

     for k, v := range data {

          fmt.Printf("%s -> %d\n", k, v)
     }
}

我们读取 items.yaml 文件的内容。

data := make(map[interface{}]interface{})

定义了用于读取数据的 map。

err2 := yaml.Unmarshal(yfile, &data)

我们将数据 unmarshal 到 map 中。

for k, v := range data {

     fmt.Printf("%s -> %d\n", k, v)
}

我们遍历 map 并打印其键和值。

$ go run read_items.go 
books -> 23
spectacles -> 2
chairs -> 12
pens -> 6
raincoat -> 1
coins -> 5

Go YAML 读取示例 II

在下一个示例中,我们读取用户。

users.yaml
user 1:
    name: John Doe
    occupation: gardener
user 2:
    name: Lucy Black
    occupation: teacher
user 3:
    name: Roger Roe
    occupation: driver

我们在文件中有一些用户。

read_users.go
package main

import (
     "fmt"
     "io/ioutil"
     "log"

     "gopkg.in/yaml.v3"
)

type User struct {
     Name       string
     Occupation string
}

func main() {

     yfile, err := ioutil.ReadFile("users.yaml")

     if err != nil {

          log.Fatal(err)
     }

     data := make(map[string]User)

     err2 := yaml.Unmarshal(yfile, &data)

     if err2 != nil {

          log.Fatal(err2)
     }

     for k, v := range data {

          fmt.Printf("%s: %s\n", k, v)
     }
}

在代码示例中,我们有 User 结构体,它代表文件中的一个用户记录。

data := make(map[string]User)

我们定义了一个用户 map。

err2 := yaml.Unmarshal(yfile, &data)

我们将数据反序列化到 map 或用户中。

$ go run read_simple.go 
user 1: {John Doe gardener}
user 2: {Lucy Black teacher}
user 3: {Roger Roe driver}

Go YAML 写入示例

我们将一些词语写入 YAML 文件。

func Marshal(in interface{}) (out []byte, err error)

Marshal 函数将提供的值序列化为 YAML 文档。

write_words.go
package main

import (
     "fmt"
     "io/ioutil"
     "log"

     "gopkg.in/yaml.v3"
)

func main() {

     words := [5]string{"falcon", "sky", "earth", "cloud", "fox"}

     data, err := yaml.Marshal(&words)

     if err != nil {
          log.Fatal(err)
     }

     err2 := ioutil.WriteFile("words.yaml", data, 0)

     if err2 != nil {

          log.Fatal(err2)
     }

     fmt.Println("data written")
}

我们有一个词语数组;数组被 Marshal 序列化为 YAML 格式,并使用 WriteFile 写入 words.yaml

$ go run write_words.go 
data written
$ cat words.yaml 
- falcon
- sky
- earth
- cloud
- fox

Go YAML 写入示例 II

在下面的示例中,我们将用户写入 YAML 文件。

write_users.go
package main

import (
     "fmt"
     "io/ioutil"
     "log"

     "gopkg.in/yaml.v3"
)

type User struct {
     Name       string
     Occupation string
}

func main() {

     users := map[string]User{"user 1": {"John Doe", "gardener"},
          "user 2": {"Lucy Black", "teacher"}}

     data, err := yaml.Marshal(&users)

     if err != nil {

          log.Fatal(err)
     }

     err2 := ioutil.WriteFile("users.yaml", data, 0)

     if err2 != nil {

          log.Fatal(err2)
     }

     fmt.Println("data written")
}

我们有一个用户 map;每个用户由一个 User 结构体表示。我们使用 Marshal 将 map 序列化为 YAML 格式,并使用 WriteFile 将数据写入 users.yaml 文件。

$ go run write_users.go 
data written
$ cat users.yaml 
user 1:
    name: John Doe
    occupation: gardener
user 2:
    name: Lucy Black
    occupation: teacher

Go YAML 写入示例 III

只有导出的结构体字段(第一个字母大写)才会被 marshall。默认情况下,它们会使用小写字段名进行 marshall。

可以通过字段标签中的 yaml 名称定义自定义键。第一个逗号之前的内容用作键,后面的逗号分隔的选项用于微调 marshalling 过程。

write_config.go
package main

import (
     "fmt"
     "io/ioutil"
     "log"

     "gopkg.in/yaml.v3"
)

type Record struct {
     Item string `yaml:"item"`
     Col  string `yaml:"colour"`
     Size string `yaml:"size"`
}

type Config struct {
     Record Record `yaml:"Settings"`
}

func main() {

     config := Config{Record: Record{Item: "window", Col: "blue", Size: "small"}}

     data, err := yaml.Marshal(&config)

     if err != nil {

          log.Fatal(err)
     }

     err2 := ioutil.WriteFile("config.yaml", data, 0)

     if err2 != nil {
          
          log.Fatal(err2)
     }

     fmt.Println("data written")
}

在代码示例中,我们写入了配置数据。

$ go run write_config.go 
data written
$ cat config.yaml 
Settings:
    item: window
    colour: blue
    size: small

来源

Go yaml - Github 页面

在本文中,我们已经使用 Go 中的 YAML 格式。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了超过 1400 篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出所有 Go 教程