Интернационализация (i18n) в Go (Golang): Полное руководство для разработчиков
Интернационализация (i18n) — это процесс проектирования программного обеспечения таким образом, чтобы его можно было легко адаптировать для различных языков и регионов без внесения изменений в исходный код. В Go (Golang) для этих целей существует несколько зрелых решений, но самым популярным и стандартизированным является пакет golang.org/x/text, который предоставляет мощные инструменты для работы с локализацией. В этой статье мы подробно разберем, как настроить i18n в Go-приложении, используя официальные библиотеки и лучшие практики.
Основные библиотеки для i18n в Go
Экосистема Go предлагает несколько подходов к интернационализации. Рассмотрим ключевые из них:
golang.org/x/text— основной пакет от команды Go, поддерживающий Unicode, CLDR (Common Locale Data Repository) и сложные правила плюрализации.github.com/nicksnyder/go-i18n— популярная сторонняя библиотека с поддержкой JSON, TOML и YAML файлов переводов, простым API и автоматическим определением языка.github.com/leonelquinteros/gotext— легковесная альтернатива, работающая с форматом GNU gettext (.po/.mo файлы), идеальна для небольших проектов.
В этом руководстве мы сосредоточимся на go-i18n как на самом сбалансированном решении для веб-приложений, но концепции применимы к любой библиотеке.
Установка и настройка go-i18n
Для начала установите библиотеку и CLI-инструмент для работы с переводами:
go get github.com/nicksnyder/go-i18n/v2/i18n
go install github.com/nicksnyder/go-i18n/v2/goi18n@latest
Создайте структуру проекта:
myapp/
├── active.en.json
├── active.ru.json
├── main.go
└── go.mod
Создание файлов переводов
Библиотека использует JSON-файлы с переводами. Пример для английского и русского языков:
active.en.json
{
"greeting": {
"other": "Hello, {{.Name}}!"
},
"cakes_count": {
"one": "You have {{.Count}} cake.",
"few": "You have {{.Count}} cakes.",
"many": "You have {{.Count}} cakes.",
"other": "You have {{.Count}} cakes."
}
}
active.ru.json
{
"greeting": {
"other": "Привет, {{.Name}}!"
},
"cakes_count": {
"one": "У вас {{.Count}} пирожное.",
"few": "У вас {{.Count}} пирожных.",
"many": "У вас {{.Count}} пирожных.",
"other": "У вас {{.Count}} пирожных."
}
}
Обратите внимание на использование правил плюрализации: one, few, many и other. В русском языке существуют 4 формы, в то время как в английском — только 2 (one/other). Библиотека автоматически выбирает правильную форму на основе числа.
Пример использования в коде
Теперь напишем код, который загружает переводы и отображает локализованные сообщения:
package main
import (
"fmt"
"log"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func main() {
// Создаем бандл с языковыми файлами
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
// Загружаем файлы переводов
_, err := bundle.LoadMessageFile("active.en.json")
if err != nil {
log.Fatal(err)
}
_, err = bundle.LoadMessageFile("active.ru.json")
if err != nil {
log.Fatal(err)
}
// Создаем локализатор для русского языка
localizer := i18n.NewLocalizer(bundle, "ru")
// Пример 1: Простое приветствие
greeting, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "greeting",
TemplateData: map[string]string{
"Name": "Алексей",
},
})
if err == nil {
fmt.Println(greeting) // Вывод: Привет, Алексей!
}
// Пример 2: Счет с плюрализацией
for _, count := range []int{1, 2, 5, 21} {
message, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "cakes_count",
PluralCount: count,
TemplateData: map[string]interface{}{
"Count": count