nil - это не просто «пусто». Иногда это причина самых странных багов в продакшене.
nil в Go - это не одно значение, а множество разных nil.
1. Interface и nil — ловушка
var err error = nil
fmt.Println(err == nil) // true
var e *MyError = nil
var err error = e
fmt.Println(err == nil) // false (!)
Почему так?
Интерфейс в Go хранит:
• тип
• значение
В этом случае:
• тип = *MyError
• значение = nil
Интерфейс не nil, потому что тип задан.
Именно так появляются ошибки вида:
if err != nil срабатывает
но внутри на самом деле nil
2. Typed nil vs untyped nil
var p *int = nil
var s []int = nil
var m map[string]int = nil
Все они nil, но разных типов.
И Go сравнивает не только значение, но и тип.
3. Panic из-за nil внутри interface
type User struct{}
func (u *User) Name() string {
return "John"
}
var u *User = nil
var i interface{} = u
i.(*User).Name() // panic
Интерфейс не nil → метод вызывается → внутри nil → panic.
4. Частый баг с error
Плохой код:
func do() error {
var e *MyError = nil
return e
}
Правильно:
func do() error {
if somethingWrong {
return &MyError{}
}
return nil
}
Главное правило
Если работаешь с interface:
• всегда проверяй, что возвращаешь чистый nil
помни:
interface != nil, если внутри typed nil
https://sushantdhiman.dev/nil-in-go-is-not-what-you-think/
