Какой вывод появится в консоли при выполнении примера №71

Исходник не компилируется из-за defer =. После исправления на defer logError(err) вывод будет everything fine, хотя do возвращает ошибку fail.

Короткий ответ

Что ответить на собеседовании

Исходник не компилируется из-за defer =. После исправления на defer logError(err) вывод будет everything fine, хотя do возвращает ошибку fail.

Подробный разбор

Ответ с пояснениями

Условие

Определите, какой текст будет напечатан в консоли после запуска следующей программы.

package main

import "fmt"
import "errors"

func main(){
    do()
}

func do () (err error){
    defer = logError(err)

    err = nil

    return errors.New("fail")
}

func logError(err error){
    if err != nil {
        fmt.Printf("error: %s", err.Error())
    }else {
        fmt.Println("everything fine")
    }
}

Ответ

Исходник не компилируется из-за defer =. После исправления на defer logError(err) вывод будет everything fine, хотя do возвращает ошибку fail.

Аргументы отложенного вызова вычисляются в момент регистрации defer. Тогда именованный результат err ещё nil, и именно это значение получает logError позднее.

return errors.New("fail") присваивает ошибку именованному результату, но не меняет уже сохранённый аргумент. Чтобы логировать итоговый err, нужен defer func() { logError(err) }(): замыкание читает переменную при выполнении. main в исходном примере игнорирует возвращённую ошибку, поэтому отдельного вывода fail не будет.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее