Исходник не компилируется из-за defer =. После исправления на defer logError(err) вывод будет everything fine, хотя do возвращает ошибку fail.
Какой вывод появится в консоли при выполнении примера №71
Исходник не компилируется из-за 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 не будет.