sync.Once гарантирует, что функция выполнится ровно один раз, даже при вызове из нескольких горутин. Классика — ленивая инициализация.
var (
instance *Database
once sync.Once
)
func GetDB() *Database {
once.Do(func() {
instance = connectToDB() // выполнится 1 раз
})
return instance
}
Ключевые свойства:
- Потокобезопасна
- Если
fпаникует — Once считается выполненной (повторный вызов НЕ ретраит) - Все горутины, вызвавшие
Doпараллельно, блокируются пока первая не завершитf
sync.OnceFunc, sync.OnceValue, sync.OnceValues:
getConfig := sync.OnceValue(func() *Config {
return loadConfig() // вызовется 1 раз, результат кешируется
})
cfg := getConfig()