В какой последовательности выполняются несколько операторов `defer` в одной функции?

Ответ

Вызовы, отложенные с помощью defer, выполняются в обратном порядке их объявления — по принципу LIFO (Last-In, First-Out).

Это можно представить как стек: каждый defer помещает свой вызов на вершину стека. Когда функция завершает свою работу (через return или достигнув конца), Go начинает выполнять вызовы с вершины этого стека.

Пример:

package main

import "fmt"

func main() {
    fmt.Println("Начало функции")

    defer fmt.Println("Выполняется первым (последний defer)") // 3-й defer
    defer fmt.Println("Выполняется вторым")                 // 2-й defer
    defer fmt.Println("Выполняется третьим (первый defer)")  // 1-й defer

    fmt.Println("Конец функции")
}

Вывод программы:

Начало функции
Конец функции
Выполняется третьим (первый defer)
Выполняется вторым
Выполняется первым (последний defer)

Такое поведение очень удобно для управления ресурсами, например, для закрытия файла и разблокировки мьютекса в порядке, обратном их захвату.