Функции пакета
Пакетные удобные функции предоставляют лаконичный 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(используется настройкаFilenamesизDefaultConfig()).
Возвращает:
error- ошибка загрузки
Поведение:
- Создаёт новый экземпляр Loader и устанавливает его как загрузчик по умолчанию
- Автоматически применяется к системному окружению (
os.Environ) - Последующие загруженные файлы могут переопределять предыдущие (управляется конфигурацией
OverwriteExisting; по умолчанию дляLoad()—false, т. е. без переопределения) - Возвращает
ErrAlreadyInitialized, если загрузчик по умолчанию уже инициализирован - Поддерживает несколько форматов (.env, JSON, YAML)
// Загрузка .env файла
if err := env.Load(".env"); err != nil {
log.Fatal(err)
}
// Загрузка указанных файлов (по порядку; для переопределения нужно установить OverwriteExisting)
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, если загрузчика ранее не было или закрытие прошло успешно
Поведение:
- После блокировки через
defaultMu.Lock()используетdefaultLoader.Swap(nil)для атомарной замены загрузчика по умолчанию на nil, затем немедленно снимает блокировку - Закрывает старый загрузчик вне блокировки (чтобы избежать потенциально длительных операций очистки при удержании блокировки, предотвращая дедлоки, если
Close()вызывает код, требующий загрузчика по умолчанию) - После сброса позволяет создать новый загрузчик по умолчанию через
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 - обработка безопасных значений
- Маппинг структур - руководство по маппингу структур