Идиома полезного нулевого значения
Вопрос
Что значит «make the zero value useful» в Go? Приведите примеры из стандартной библиотеки и расскажите, как вы проектируете свои типы с учётом этого.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Любая переменная Go инициализирована нулевым значением, мусора нет
Тип удобно проектировать так, чтобы нулевое значение было готово к работе без конструктора
Примеры: `sync.Mutex`, `bytes.Buffer`, `strings.Builder`, `sync.WaitGroup`
nil-слайс работает с append и len, а nil-мапа ломается на записи: ленивая инициализация мапы в методе
Когда нулевое значение невалидно, нужен конструктор `NewX` и неэкспортируемые поля
Что могут спросить следом
- Можно ли вызвать метод на nil-указателе?
- Как сделать ленивую инициализацию мапы внутри структуры безопасно для горутин?
Разбор
В Go нет неинициализированной памяти: объявленная переменная получает нулевое значение типа. Идиома в том, чтобы это значение сразу было полезным. var mu sync.Mutex уже разблокированный мьютекс, var buf bytes.Buffer пустой буфер, готовый к записи, var sb strings.Builder тоже. Свои типы я проектирую так же: поля, у которых ноль осмыслен (счётчики, флаги, nil-слайсы), не требуют конструктора. Мапу внутри структуры создаю лениво в методе записи: if c.m == nil { c.m = make(map[K]V) }, под тем же мьютексом, если тип конкурентный. Если нулевое значение недопустимо, например нужен адрес сервера или клиент базы, делаю конструктор NewClient(cfg) и неэкспортируемые поля, чтобы снаружи не собрали полуготовый объект. Ещё приём: метод на nil-указателе может работать, если внутри проверить ресивер на nil.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Типы и нулевые значения»
- Перевод числа между системами счисления на Go
- Права доступа битовой маской на Go
- Наименьший целый тип для суммы на Go
- Что выведет Go: преобразования чисел
- Что выведет Go: iota с выражением
- Что выведет Go: затенение переменной в if
- type A = B и type A B
- byte и rune