Работа с YAML в Go (Golang) — библиотеки gopkg.in/yaml.v3 и encoding/json

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с YAML в Go (Golang) — библиотека 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. В этой статье мы подробно разберём, как читать, писать и обрабатывать YAML в Go.

Установка библиотеки

Для начала работы добавьте пакет в ваш проект:

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\n", cfg.Server.Host, cfg.Server.Port)
    fmt.Printf("База: %s\n", 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\n", s.Name, s.Ports, s.Enabled)
    }
}

Потоковое чтение и запись (Decoder/Encoder)

Для работы с большими файлами или потоками данных используйте yaml.Decoder и yaml.Encoder:

package main

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

func main() {
    // Пример с Encoder
    var buf bytes.Buffer
    encoder := yaml.NewEncoder(&buf)
    encoder.SetIndent(2) // настройка отступов
    data := map                    

Рекомендаций