在 Go (Golang) 中处理 YAML — 库 gopkg.in/yaml.v3 和 encoding/json

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在 Go (Golang) 中处理 YAML — 库 gopkg.in/yaml.v3



YAML (YAML Ain't Markup Language) 是一种流行的数据序列化格式,常用于配置文件、API 描述 (OpenAPI/Swagger)、CI/CD 流水线 (GitLab CI, GitHub Actions) 和 Docker Compose。在 Go (Golang) 生态系统中,没有用于处理 YAML 的标准库,因此开发者使用强大且稳定的第三方库 gopkg.in/yaml.v3。在本文中,我们将详细介绍如何在 Go 中读取、写入和处理 YAML。



安装库

首先,将包添加到您的项目中:

go get gopkg.in/yaml.v3

之后,将其导入到代码中:

import "gopkg.in/yaml.v3"


处理 YAML 的基本结构

yaml.v3 库支持:

  • 序列化 (Marshal) — 将 Go 结构转换为 YAML 字符串。
  • 反序列化 (Unmarshal) — 将 YAML 字符串解析为 Go 结构。
  • 流式解析 (Decoder/Encoder) 用于处理文件。
  • 标签 yaml:"fieldname" 用于配置字段名称。


示例 1:从字符串读取 YAML

最简单的情况是将 YAML 字符串解析为 Go 结构:

package main

import ( "fmt" "gopkg.in/yaml.v3")

type Config struct { Server struct { Port int `yaml:"port"` Host string `yaml:"host"` } `yaml:"server"` Database struct { User string `yaml:"user"` Pass string `yaml:"pass"` } `yaml:"database"`}

func main() { yamlData := `server: port: 8080 host: "localhost"database: user: "admin" pass: "secret"` var cfg Config err := yaml.Unmarshal([]byte(yamlData), &cfg) if err != nil { panic(err) } fmt.Printf("服务器: %s:%d", cfg.Server.Host, cfg.Server.Port) fmt.Printf("数据库: %s", cfg.Database.User)}


示例 2:将 YAML 写入文件

要将数据写入 YAML 文件,请使用 yaml.Marshal 并写入文件系统:

package main

import ( "os" "gopkg.in/yaml.v3")

type AppConfig struct { Name string `yaml:"name"` Version string `yaml:"version"` Debug bool `yaml:"debug"`}

func main() { config := AppConfig{ Name: "MyApp", Version: "1.0.0", Debug: true, }

data, err := yaml.Marshal(&config) if err != nil { panic(err) }

err = os.WriteFile("config.yaml", data, 0644) if err != nil { panic(err) } println("文件 config.yaml 已创建")}


示例 3:处理嵌套和复杂结构

YAML 支持列表、map 结构和深层嵌套。以下是一个解析服务器列表的示例:

package main

import ( "fmt" "gopkg.in/yaml.v3")

type Service struct { Name string `yaml:"name"` Ports []int `yaml:"ports"` Enabled bool `yaml:"enabled"`}

type Deployment struct { Version string `yaml:"version"` Services []Service `yaml:"services"`}

func main() { input := `version: "2.1"services: - name: web ports: [80, 443] enabled: true - name: api ports: [3000] enabled: false` var dep Deployment if err := yaml.Unmarshal([]byte(input), &dep); err != nil { panic(err) }

for _, s := range dep.Services { fmt.Printf("服务 %s: 端口 %v, 启用: %t", s.Name, s.Ports, s.Enabled) }}


流式读取和写入 (Decoder/Encoder)

对于处理大文件或数据流,请使用 yaml.Decoder 和 yaml.Encoder:

package main

import ( "

推荐