Singleton гарантирует единственный экземпляр объекта на всё приложение. В Go реализуется через sync.Once:
var (
instance *Database
once sync.Once
)
func GetDB() *Database {
once.Do(func() {
instance = &Database{}
})
return instance
}
sync.Once потокобезопасен — инициализация произойдёт ровно один раз, даже при конкурентных вызовах. Альтернатива — init() функция, но она не даёт ленивой инициализации. Singleton усложняет тестирование, поэтому в Go чаще предпочитают явную передачу зависимостей (DI).