Оператор defer откладывает выполнение функции до тех пор, пока не вернется окружающая функция, либо в обычном режиме, либо через panic.
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
Вывод:
Hello
World
Отложенные вызовы выполняются даже при панике функции:
func main() {
defer fmt.Println("World")
panic("Stop")
fmt.Println("Hello")
}
Вывод:
World
panic: Stop
goroutine 1 [running]:
main.main()
../main.go:3 +0xa0
Порядок исполнения
Аргументы отложенного вызова вычисляются немедленно, даже если вызов функции не выполняется до тех пор, пока не вернется окружающая функция.
Если имеется несколько отложенных вызовов функций, они выполняются в порядке "последний пришел - первым вышел".
func main() {
fmt.Println("Hello")
for i := 1; i <= 3; i++ {
defer fmt.Println(i)
}
fmt.Println("World")
}
Вывод:
Hello
World
3
2
1
Используйте func для возврата значения
Отложенные анонимные функции могут получать доступ и изменять именованные возвращаемые параметры окружающей функции.
В этом примере функция foo возвращает "Change World".
func foo() (result string) {
defer func() {
// изменяет значение в самый последний момент
result = "Change World"
}()
return "Hello World"
}
Применение defer
Defer часто используется для выполнения действий по очистке, таких как закрытие файла или разблокировка мьютекса. Такие действия должны выполняться как в случаях когда функция возвращается нормально, так и когда она паникует.
Закрытие файла
В этом примере операторы defer используются для того, чтобы все файлы были закрыты перед выходом из функции CopyFile, в зависимости от того, как это происходит.
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}
Обработка ошибок: поймать panic
Defer также может быть использован для восстановления (recover) после panic и обновления возвращаемого значения.
Читайте также:
Комментариев нет:
Отправить комментарий