Для одного экземпляра достаточно sync.Once. Экземпляр на каждую пару name и age — уже multiton: кеш по составному ключу, защищённый mutex.
Напиши Singleton на Go с использованием sync.Once, затем усложни: GetLogger принимает name и age, возвращает один экземпляр для одинаковых параметров
Для одного экземпляра достаточно sync.Once. Экземпляр на каждую пару name и age — уже multiton: кеш по составному ключу, защищённый mutex.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Для одного экземпляра достаточно sync.Once. Экземпляр на каждую пару name и age — уже multiton: кеш по составному ключу, защищённый mutex.
type Logger struct { name string; age int }
var singletonOnce sync.Once
var singleton *Logger
func GetSingleton() *Logger {
singletonOnce.Do(func() { singleton = &Logger{} })
return singleton
}
type loggerKey struct { name string; age int }
var loggersMu sync.Mutex
var loggers = make(map[loggerKey]*Logger)
func GetLogger(name string, age int) *Logger {
key := loggerKey{name, age}
loggersMu.Lock()
defer loggersMu.Unlock()
if logger, ok := loggers[key]; ok { return logger }
logger := &Logger{name: name, age: age}
loggers[key] = logger
return logger
}
Нужен импорт sync. Конструктор в примере дешёвый; длительную инициализацию лучше согласовывать отдельным once на ключ. После создания поля считаются неизменяемыми. Для неограниченного набора ключей нужна политика удаления, иначе кеш растёт бесконечно.