Найти в Дзене
PRO Go

defer: штука, которую сначала не понимаешь

Ты читаешь чужой код и видишь defer. А сам никогда не использовал. И думаешь: А зачем это вообще нужно? Пока всё просто — функции короткие, ошибок мало, ресурсы не требуют закрытия. Но потом появляется реальный код — с кучей проверок, return в середине, и вдруг оказывается, что ты забыл что‑то сделать перед выходом. Как выглядит боль: func calc() (int, error) { if err := check(); err != nil { return 0, err } fmt.Println("start") if somethingWrong { return 0, fmt.Errorf("bad input") } fmt.Println("finish") // не выполнится, если return раньше return 42, nil } Если в середине случится ошибка — finish не выведется. А если таких действий несколько — всё превращается в хаос. Как defer решает это спокойно: func calc() (int, error) { fmt.Println("start") defer fmt.Println("finish") // выполнится всегда, даже при ошибке if somethingWrong { return 0, fmt.Errorf("bad input") } return 42, nil } Теперь не важно, где ты выйдешь из функции — finish выведется. Без лишних if, без дублирования, без заб

Ты читаешь чужой код и видишь defer.

А сам никогда не использовал.

И думаешь: А зачем это вообще нужно?

Пока всё просто — функции короткие, ошибок мало, ресурсы не требуют закрытия.

Но потом появляется реальный код — с кучей проверок, return в середине, и вдруг оказывается, что ты забыл что‑то сделать перед выходом.

Как выглядит боль:

func calc() (int, error) {
if err := check(); err != nil {
return 0, err
}
fmt.Println("start")
if somethingWrong {
return 0, fmt.Errorf("bad input")
}
fmt.Println("finish") // не выполнится, если return раньше
return 42, nil
}

Если в середине случится ошибка — finish не выведется.

А если таких действий несколько — всё превращается в хаос.

Как defer решает это спокойно:
func calc() (int, error) {
fmt.Println("start")
defer fmt.Println("finish") // выполнится всегда, даже при ошибке
if somethingWrong {
return 0, fmt.Errorf("bad input")
}
return 42, nil
}

Теперь не важно, где ты выйдешь из функции — finish выведется.

Без лишних if, без дублирования, без забытых вызовов.

Что важно понять

defer — выполняет нужные действия при любом исходе, убирает дублирование, делает функции чище и предсказуемее.

На базовом уровне у тебя нет кода, где это нужно.

Нет длинных функций, нет промежуточных выходов.

А когда они появляются — defer становится настоящим спасением.