Функции пакета
Пакетные удобные функции предоставляют лаконичный API, подходящий для большинства сценариев использования. Эти функции используют глобальный загрузчик по умолчанию, все функции потокобезопасны.
Требуется инициализация
Глобальный загрузчик по умолчанию должен быть явно инициализирован через Load() или LoadWithConfig() и не создаётся автоматически при первом вызове. Без инициализации функции ведут себя так:
- Функции
Get*(GetString,GetInt,GetBoolи т. д.): возвращают переданное значение по умолчанию (или нулевое значение) Lookup: возвращает("", false)Keys/All/Len/GetSecure: возвращаютnil/0Set/Delete/Validate/ParseInto: возвращаютErrNotInitialized
Функции загрузки
Load
func Load(filenames ...string) errorЗагружает файлы переменных окружения и применяет к системному окружению.
Параметры:
filenames- Список путей к файлам. Если не предоставлен, файлы не загружаются; необходимо явно передать".env"для загрузки файла по умолчанию.
Возвращает:
error- Ошибка загрузки
Поведение:
- Создаёт новый экземпляр Loader и устанавливает его как загрузчик по умолчанию
- Автоматически применяется к системному окружению (
os.Environ) - Файлы, загруженные позже, перезаписывают загруженные ранее
- Возвращает
ErrAlreadyInitialized, если загрузчик по умолчанию уже инициализирован - Поддерживает несколько форматов (.env, JSON, YAML)
// Загрузка файла .env
if err := env.Load(".env"); err != nil {
log.Fatal(err)
}
// Загрузка указанных файлов (по порядку, поздние перезаписывают ранние)
if err := env.Load(".env", ".env.local", "config.json"); err != nil {
log.Fatal(err)
}
// Вложенные структуры JSON/YAML поддерживают доступ через точку
// config.json: {"database": {"host": "localhost", "port": 5432}}
env.Load("config.json")
host := env.GetString("database.host") // "localhost"
port := env.GetInt("database.port") // 5432Разрешение имён ключей
Все функции получения поддерживают интеллектуальное разрешение имён ключей, обеспечивая гибкий доступ.
Правила разрешения
1. Точное совпадение (приоритет)
// .env: APP_NAME=myapp
name := env.GetString("APP_NAME") // "myapp"2. Преобразование в верхний регистр (простые ключи)
// Для ключей без точек автоматически пробуется версия в верхнем регистре
name := env.GetString("app_name") // Поиск app_name -> APP_NAME3. Разрешение пути через точку (вложенные ключи)
// JSON: {"app": {"name": "myapp"}}
// Хранится как: APP_NAME=myapp
// Все следующие способы позволяют получить значение
name := env.GetString("APP_NAME") // Плоское имя ключа (рекомендуется)
name := env.GetString("app.name") // Путь через точку (автоматическое преобразование)
name := env.GetString("APP.NAME") // Путь через точку в верхнем регистреТаблица преобразования путей
| Входное имя ключа | Имя ключа хранения |
|---|---|
"database.host" | "DATABASE_HOST" |
"db.port" | "DB_PORT" |
"servers.0.host" | "SERVERS_0_HOST" |
"app.config.name" | "APP_CONFIG_NAME" |
Доступ по индексу
Элементы массива доступны по индексу, или откат к значениям, разделённым запятыми:
// JSON: {"servers": [{"host": "a.com"}, {"host": "b.com"}]}
// Хранится как: SERVERS_0_HOST=a.com, SERVERS_1_HOST=b.com
host0 := env.GetString("servers.0.host") // "a.com"
host1 := env.GetString("servers.1.host") // "b.com"
// Если ключ не существует, но есть значение с разделителями-запятыми
// HOSTS=localhost,example.com
host0 := env.GetString("hosts.0") // "localhost" (разобрано из значения с разделителями-запятыми)Функции получения значений
GetString
func GetString(key string, defaultValue ...string) stringПолучает строковое значение. Поддерживает разрешение пути через точку.
Параметры:
key- Имя ключа (поддерживает точное совпадение, преобразование регистра, путь через точку)defaultValue- Необязательное значение по умолчанию
Возвращает:
string- Значение или значение по умолчанию (возвращает пустую строку, если не найдено и нет значения по умолчанию)
// Базовое использование
host := env.GetString("HOST", "localhost")
// Доступ через путь с точкой (вложенные структуры JSON/YAML)
dbHost := env.GetString("database.host", "localhost")
appName := env.GetString("app.name")
// Возвращает пустую строку при отсутствии значения по умолчанию
value := env.GetString("NON_EXISTENT") // ""GetInt
func GetInt(key string, defaultValue ...int64) int64Получает целочисленное значение. Автоматически преобразует строку в целое число. Поддерживает разрешение пути через точку.
Параметры:
key- Имя ключа (поддерживает путь через точку)defaultValue- Необязательное значение по умолчанию, типint64
Возвращает:
int64- Значение или значение по умолчанию (возвращает 0, если не найдено и нет значения по умолчанию)
port := env.GetInt("PORT", 8080)
maxConn := env.GetInt("database.max_connections", 10)
// Возвращает 0 при отсутствии значения по умолчанию
value := env.GetInt("NON_EXISTENT") // 0GetBool
func GetBool(key string, defaultValue ...bool) boolПолучает логическое значение. Поддерживает разрешение пути через точку.
- Истинные значения (без учёта регистра):
true,1,yes,on,enabled - Ложные значения (без учёта регистра):
false,0,no,off,disabled
Параметры:
key- Имя ключа (поддерживает путь через точку)defaultValue- Необязательное значение по умолчанию
Возвращает:
bool- Значение или значение по умолчанию (возвращает false, если не найдено и нет значения по умолчанию)
debug := env.GetBool("DEBUG", false)
cacheEnabled := env.GetBool("cache.enabled", true)
// Возвращает false при отсутствии значения по умолчанию
value := env.GetBool("NON_EXISTENT") // falseGetUint64
func GetUint64(key string, defaultValue ...uint64) uint64Получает беззнаковое целочисленное значение. Поддерживает разрешение пути через точку.
Параметры:
key- Имя ключа (поддерживает путь через точку)defaultValue- Необязательное значение по умолчанию, типuint64
Возвращает:
uint64- Значение или значение по умолчанию (возвращает 0, если не найдено и нет значения по умолчанию)
port := env.GetUint64("PORT", 8080)
maxSize := env.GetUint64("MAX_SIZE", 1024)
// Возвращает 0 при отсутствии значения по умолчанию
value := env.GetUint64("NON_EXISTENT") // 0GetFloat64
func GetFloat64(key string, defaultValue ...float64) float64Получает значение с плавающей точкой. Поддерживает разрешение пути через точку.
Параметры:
key- Имя ключа (поддерживает путь через точку)defaultValue- Необязательное значение по умолчанию, типfloat64
Возвращает:
float64- Значение или значение по умолчанию (возвращает 0, если не найдено и нет значения по умолчанию)
rate := env.GetFloat64("RATE", 0.5)
threshold := env.GetFloat64("THRESHOLD")
// Возвращает 0 при отсутствии значения по умолчанию
value := env.GetFloat64("NON_EXISTENT") // 0GetDuration
func GetDuration(key string, defaultValue ...time.Duration) time.DurationПолучает значение временного интервала. Поддерживает разрешение пути через точку.
Поддерживаемые форматы:
300ms- Миллисекунды1.5s- Секунды2m30s- Минуты + секунды1h30m- Часы + минуты
Параметры:
key- Имя ключа (поддерживает путь через точку)defaultValue- Необязательное значение по умолчанию
Возвращает:
time.Duration- Значение или значение по умолчанию (возвращает 0, если не найдено и нет значения по умолчанию)
timeout := env.GetDuration("TIMEOUT", 30*time.Second)
interval := env.GetDuration("INTERVAL", 5*time.Minute)
// Возвращает 0 при отсутствии значения по умолчанию
value := env.GetDuration("NON_EXISTENT") // 0GetSecure
func GetSecure(key string) *SecureValueПолучает безопасное значение (для конфиденциальных данных).
Параметры:
key- Имя ключа
Возвращает:
*SecureValue- Обёртка безопасного значения; nil если ключ не существует или загрузчик недоступен
secret := env.GetSecure("API_KEY")
if secret != nil {
defer secret.Release()
value := secret.Reveal() // открытое значение (вызывать только при необходимости)
masked := secret.Masked() // для логов: [SECURE:32 bytes]
}Важно
После использования необходимо вызвать Release() или Close() для освобождения ресурсов. Рекомендуется использовать defer для гарантии освобождения.
Подробнее
SecureValue API - полная документация API.
GetSlice[T]
func GetSlice[T sliceElement](key string, defaultValue ...[]T) []TУниверсальная функция, получает значение среза.
Поддерживаемые типы: string, int, int64, uint, uint64, bool, float64, time.Duration
Примечание: Это универсальная функция, а не метод Loader. Для получения среза из указанного экземпляра Loader используйте GetSliceFrom[T].
Порядок разбора:
- Сначала поиск индексных ключей
KEY_0,KEY_1,KEY_2... - Если индексных ключей нет, разбор значения
KEYпо запятым - Поддерживает разрешение пути через точку
Параметры:
key- Имя ключаdefaultValue- Необязательное значение по умолчанию
Возвращает:
[]T- Значение среза
// Формат индексных ключей (рекомендуется)
// HOSTS_0=localhost
// HOSTS_1=example.com
hosts := env.GetSlice[string]("HOSTS") // ["localhost", "example.com"]
// Формат с запятыми
// PORTS=80,443,8080
ports := env.GetSlice[int64]("PORTS", []int64{80}) // [80, 443, 8080]
// Срез чисел с плавающей точкой
rates := env.GetSlice[float64]("RATES", []float64{0.1, 0.2})
// Срез логических значений
flags := env.GetSlice[bool]("FLAGS")
// Срез Duration
timeouts := env.GetSlice[time.Duration]("TIMEOUTS")
// Срез беззнаковых целых
ports := env.GetSlice[uint]("PORTS")
port64s := env.GetSlice[uint64]("PORTS")
// Тип int
portInts := env.GetSlice[int]("PORTS")
// Возвращает nil при отсутствии значения по умолчанию
value := env.GetSlice[string]("NON_EXISTENT") // nilGetSliceFrom[T]
func GetSliceFrom[T sliceElement](loader *Loader, key string, defaultValue ...[]T) []TПолучает значение среза из указанного экземпляра Loader. Это отдельная универсальная функция (не метод Loader).
Параметры:
loader- Указатель на экземпляр Loader (если nil, возвращает значение по умолчанию)key- Имя ключаdefaultValue- Необязательное значение по умолчанию
Возвращает:
[]T- Значение среза
Поддерживаемые типы: string, int, int64, uint, uint64, bool, float64, time.Duration
loader, _ := env.New(cfg)
defer loader.Close()
// Получение среза из экземпляра loader
hosts := env.GetSliceFrom[string](loader, "HOSTS")
ports := env.GetSliceFrom[int64](loader, "PORTS", []int64{80})
// Также поддерживает типы int, uint, uint64
portsInt := env.GetSliceFrom[int](loader, "PORTS")
portsUint := env.GetSliceFrom[uint](loader, "PORTS")
portsUint64 := env.GetSliceFrom[uint64](loader, "PORTS")Разница
GetSlice[T]- Пакетная функция, использующая загрузчик по умолчаниюGetSliceFrom[T]- Универсальная функция для указанного экземпляра Loader (Go не поддерживает универсальные методы)
Функции запросов
Lookup
func Lookup(key string) (string, bool)Проверяет существование ключа и получает значение. Поддерживает разрешение пути через точку.
Параметры:
key- Имя ключа (поддерживает путь через точку)
Возвращает:
string- Значение (начальные и конечные пробелы удалены)bool- Существует ли
value, exists := env.Lookup("API_KEY")
if !exists {
// Ключ не существует
}
// Путь через точку
if value, exists := env.Lookup("database.host"); exists {
fmt.Println(value)
}Keys
func Keys() []stringПолучает все имена ключей.
Возвращает:
[]string- Список ключей; nil если загрузчик недоступен
keys := env.Keys()
for _, key := range keys {
fmt.Println(key)
}All
func All() map[string]stringПолучает все пары ключ-значение.
Возвращает:
map[string]string- Маппинг ключ-значение; nil если загрузчик недоступен
all := env.All()
for key, value := range all {
fmt.Printf("%s=%s\n", key, value)
}Len
func Len() intПолучает количество переменных.
Возвращает:
int- Количество переменных; 0 если загрузчик недоступен
count := env.Len()
fmt.Printf("Загружено %d переменных окружения\n", count)Установка и удаление
Set
func Set(key, value string) errorУстанавливает переменную окружения.
Параметры:
key- Имя ключаvalue- Значение
Возвращает:
error- Ошибка установки
Типы ошибок:
*ValidationError- Недопустимый формат имени ключа (Field="key")*SecurityError- Ключ запрещён (можно сопоставить черезerrors.Is(err, env.ErrSecurityViolation))ErrInvalidValue- Недопустимое значение (когдаValidateValuesравно true, значение содержит небезопасный контент: нулевые байты, управляющие символы)ErrClosed- Загрузчик закрыт
if err := env.Set("CUSTOM_KEY", "value"); err != nil {
// Может быть *SecurityError (запрещённый ключ) или *ValidationError (формат ключа)
}Delete
func Delete(key string) errorУдаляет переменную окружения.
Параметры:
key- Имя ключа
Возвращает:
error- Ошибка удаления
if err := env.Delete("TEMP_KEY"); err != nil {
panic(err)
}Валидация и маппинг
Validate
func Validate() errorПроверяет наличие обязательных ключей. Необходимо установить RequiredKeys в Config.
Возвращает:
error- Ошибка валидации
// Необходимо сначала настроить RequiredKeys (через пользовательский загрузчик)
cfg := env.ProductionConfig()
cfg.RequiredKeys = []string{"DB_HOST", "API_KEY"}
loader, _ := env.New(cfg)
loader.LoadFiles(".env")
if err := loader.Validate(); err != nil {
// Отсутствует обязательный ключ
}ParseInto
func ParseInto(v any) errorМаппит переменные окружения в структуру.
Параметры:
v- Указатель на структуру
Возвращает:
error- Ошибка маппинга
type Config struct {
Host string `env:"HOST" envDefault:"localhost"`
Port int64 `env:"PORT" envDefault:"8080"`
}
var cfg Config
if err := env.ParseInto(&cfg); err != nil {
panic(err)
}Теги структуры:
| Тег | Описание |
|---|---|
env:"KEY" | Маппинг на указанный ключ |
env:"-" | Игнорировать это поле |
envDefault:"value" | Значение по умолчанию |
По умолчанию поля-срезы разделяются запятой , (пробелы вокруг разделителя удаляются автоматически), пользовательского тега разделителя нет.
Подробнее
Маппинг структур - полное руководство.
Служебные функции
ResetDefaultLoader
func ResetDefaultLoader() errorСбрасывает глобальный загрузчик по умолчанию. В основном используется в сценариях тестирования.
Возвращает:
error- Ошибка закрытия старого загрузчика (если он существует); nil если загрузчика не было или закрытие успешно
Поведение:
- Атомарно заменяет загрузчик по умолчанию на nil через
atomic.Pointer.Swap - Закрывает старый загрузчик, удерживая блокировку
defaultMu(блокировка снимается только после завершения закрытия, что обеспечивает атомарность сброса) - После сброса можно создать новый загрузчик по умолчанию через
Load()илиLoadWithConfig()
func TestMain(m *testing.M) {
if err := env.ResetDefaultLoader(); err != nil {
log.Printf("warning: failed to reset loader: %v", err)
}
os.Exit(m.Run())
}
func TestSomething(t *testing.T) {
if err := env.ResetDefaultLoader(); err != nil {
t.Logf("warning: %v", err)
}
defer env.ResetDefaultLoader()
// ... код теста
}Внимание
Эта функция потокобезопасна, но вызывайте её только при тестировании или запуске, чтобы избежать непредвиденного поведения.
LoadWithConfig
func LoadWithConfig(cfg Config) errorИнициализирует загрузчик по умолчанию с пользовательской конфигурацией.
Параметры:
cfg- Пользовательская конфигурация
Возвращает:
error- Ошибка инициализации
Поведение:
- Устанавливает пакетный загрузчик по умолчанию (используемый функциями
GetString,GetIntи др.) - Принудительно
AutoApply = true(независимо от настройки в cfg) - Возвращает
ErrAlreadyInitialized, если загрузчик по умолчанию уже инициализирован
Отличие от Load:
Load()- принимает только список имён файлов, использует конфигурацию по умолчаниюLoadWithConfig()- принимает полную Config, поддерживает все параметры
cfg := env.DefaultConfig()
cfg.Filenames = []string{".env.production"}
cfg.OverwriteExisting = true
if err := env.LoadWithConfig(cfg); err != nil {
log.Fatal(err)
}
// Теперь можно использовать функции уровня пакета
port := env.GetInt("PORT", 8080)Внимание
Эта функция принудительно устанавливает cfg.AutoApply в true, обеспечивая применение переменных к системному окружению. Для контроля момента применения используйте New() для создания независимого экземпляра.
Функции сериализации
Marshal
func Marshal(data any, format ...FileFormat) (string, error)Сериализует данные в строку указанного формата. Поддерживает map[string]string или структуры в качестве входных данных.
Интеграция интерфейсов: Если входной тип реализует интерфейс Marshaler, приоритет отдаётся вызову метода MarshalEnv() для сериализации.
Параметры:
data- Данные для сериализации (map или структура)format- Необязательный формат, по умолчаниюFormatEnv
Возвращает:
string- Сериализованная строка (ключи отсортированы)error- Ошибка сериализации
Поддерживаемые форматы:
FormatEnv(по умолчанию) - Формат .envFormatJSON- Формат JSONFormatYAML- Формат YAML
// map в формат .env
mapData := map[string]string{"HOST": "localhost", "PORT": "8080"}
envStr, _ := env.Marshal(mapData)
// HOST=localhost
// PORT=8080
// map в формат JSON
jsonStr, _ := env.Marshal(mapData, env.FormatJSON)
// {
// "HOST": "localhost",
// "PORT": 8080
// }
// Структура в формат .env
type Config struct {
Host string `env:"HOST"`
Port string `env:"PORT"`
}
envStr, _ := env.Marshal(Config{Host: "localhost", Port: "8080"})UnmarshalMap
func UnmarshalMap(data string, format ...FileFormat) (map[string]string, error)Разбирает форматированную строку в map. Поддерживает автоматическое определение формата.
Параметры:
data- Форматированная строкаformat- Необязательный формат, по умолчаниюFormatEnv; используйтеFormatAutoдля автоматического определения
Возвращает:
map[string]string- Разобранные пары ключ-значениеerror- Ошибка разбора
// Формат .env
m, _ := env.UnmarshalMap("HOST=localhost\nPORT=8080")
// Формат JSON (вложенные структуры будут плоскими)
m, _ := env.UnmarshalMap(`{"database": {"host": "localhost"}}`, env.FormatJSON)
// m["DATABASE_HOST"] = "localhost"
// Автоматическое определение формата
m, _ := env.UnmarshalMap(jsonString, env.FormatAuto)UnmarshalStruct
func UnmarshalStruct(data string, v any, format ...FileFormat) errorРазбирает форматированную строку и заполняет структуру.
Параметры:
data- Форматированная строкаv- Указатель на структуруformat- Необязательный формат, по умолчаниюFormatEnv
Возвращает:
error- Ошибка разбора
type Config struct {
Host string `env:"SERVER_HOST"`
Port int `env:"SERVER_PORT"`
}
var cfg Config
err := env.UnmarshalStruct("SERVER_HOST=localhost\nSERVER_PORT=8080", &cfg)
// cfg.Host = "localhost", cfg.Port = 8080
// Разбор из JSON
err = env.UnmarshalStruct(`{"server": {"host": "localhost"}}`, &cfg, env.FormatJSON)UnmarshalInto
func UnmarshalInto(data map[string]string, v any) errorЗаполняет структуру из map. Поддерживает теги env и envDefault.
Интеграция интерфейсов: Если целевой тип реализует интерфейс Unmarshaler, приоритет отдаётся вызову метода UnmarshalEnv(data).
Параметры:
data- Отображение пар ключ-значениеv- Указатель на структуру
Возвращает:
error- Ошибка заполнения
type Config struct {
Host string `env:"HOST" envDefault:"localhost"`
Port int `env:"PORT" envDefault:"8080"`
}
data := map[string]string{"HOST": "example.com"}
var cfg Config
err := env.UnmarshalInto(data, &cfg)
// cfg.Host = "example.com", cfg.Port = 8080 (используется значение по умолчанию)MarshalStruct
func MarshalStruct(v any) (map[string]string, error)Преобразует структуру в map. Поддерживает тег env для указания имени ключа.
Интеграция интерфейсов: Если входной тип реализует интерфейс Marshaler, приоритет отдаётся вызову метода MarshalEnv().
Параметры:
v- Структура или указатель на структуру
Возвращает:
map[string]string- Отображение пар ключ-значениеerror- Ошибка преобразования
type Config struct {
Host string `env:"SERVER_HOST"`
Port int `env:"SERVER_PORT"`
}
cfg := Config{Host: "localhost", Port: 8080}
m, _ := env.MarshalStruct(cfg)
// m["SERVER_HOST"] = "localhost"
// m["SERVER_PORT"] = "8080"IsMarshalError
func IsMarshalError(err error) boolПроверяет, является ли ошибка ошибкой сериализации/десериализации.
Параметры:
err- Проверяемая ошибка
Возвращает:
bool- Является ли ошибкой типа MarshalError
_, err := env.MarshalStruct(invalidData)
if env.IsMarshalError(err) {
// Обработка ошибки сериализации
}Полный пример
package main
import (
"fmt"
"log"
"time"
"github.com/cybergodev/env"
)
type AppConfig struct {
Host string `env:"APP_HOST" envDefault:"0.0.0.0"`
Port int64 `env:"APP_PORT" envDefault:"8080"`
Debug bool `env:"DEBUG" envDefault:"false"`
Timeout time.Duration `env:"TIMEOUT" envDefault:"30s"`
Hosts []string `env:"HOSTS"`
}
func main() {
// Загрузка файла конфигурации
if err := env.Load(".env"); err != nil {
log.Printf("Warning: %v", err)
}
// Чтение отдельных значений
host := env.GetString("APP_HOST", "localhost")
port := env.GetInt("APP_PORT", 8080)
debug := env.GetBool("DEBUG", false)
timeout := env.GetDuration("TIMEOUT", 30*time.Second)
fmt.Printf("Server: %s:%d\n", host, port)
fmt.Printf("Debug: %v, Timeout: %v\n", debug, timeout)
// Конфиденциальные данные
secret := env.GetSecure("API_KEY")
if secret != nil {
defer secret.Release()
fmt.Printf("API Key length: %d\n", secret.Length())
}
// Маппинг структур
var cfg AppConfig
if err := env.ParseInto(&cfg); err != nil {
log.Fatal(err)
}
fmt.Printf("Config: %+v\n", cfg)
// Все переменные
fmt.Printf("Loaded %d variables\n", env.Len())
}Связанная документация
- Loader API - Методы экземпляра Loader
- Config API - Параметры конфигурации
- SecureValue API - Обработка безопасных значений
- Маппинг структур - Руководство по маппингу структур