Автор статьи разбирает одну из тех привычек в Go, которая на первый взгляд кажется безопасной, а на деле превращает код в кашу. Речь о бесконтрольных проверках на nil.
Выглядит логично: проверяешь указатель — предотвращаешь панику. Но проблема в том, что эти проверки почти всегда врут читателю. Если у тебя в структуре RateLimiter лежит Redis клиент, и ты проверяешь r.redis != nil перед каждым вызовом — это не защита, а симптом. Ты строишь объект с nil-зависимостью, хотя ошибка произошла в момент инициализации. Проверка на nil в методе просто прячет эту ошибку, позволяя программе работать в невалидном состоянии. Go учит fail fast, а тут — silent failure.
Можно попытаться сдвинуть проверку в конструктор и вернуть ошибку. Но и это полумера. Ты всё равно пропускаешь nil в систему, просто перекладываешь работу на следующий слой. Настоящее место для обработки — место инициализации. Если новый Redis клиент вернул ошибку, ты должен остановиться и обработать её, а не передавать nil дальше. Если система должна терпеть временную недоступность хранилища — модель это явно, оберни в тип, который всегда не-nil и сам решает, что делать с ошибками ретраями или деградацией.
Автор проводит аналогию с базой данных. Ты ставишь NOT NULL на колонку, и каждый запрос знает, что там не будет пустоты. То же самое нужно делать в коде: установить инвариант один раз, чтобы во всех внутренних функциях на него полагаться без повторяющихся проверок.
Дальше автор разбирает второй сценарий — проверка на nil у запроса внутри метода Allow. Это та же ошибка, но с другой стороны. Запрос приходит извне, на границе системы — в HTTP хендлере или обработчике RPC. Проверять его на nil нужно именно там, на границе, где ты не контролируешь входные данные. После того, как ты распарсил запрос в свою структуру, он становится внутренним доверенным значением. И Allow больше не должен его перепроверять — он доверяет тому, что уже гарантировано.
Вывод простой. Nil проверка хороша, когда она стоит на границе системы или моделирует явное необязательное состояние. Но когда проверки на nil размазаны по всему коду, это либо признак того, что не установлены инварианты, либо ты просто маскируешь проблемы. Решение — не плодить новые проверки, а постепенно выстраивать гарантии, на которые можно положиться.