Задачи на defer

1) Что выведет данная программа и почему?

package main

func main() {
	digits := []int {1, 2, 3, 4, 5}
	for _, d := range digits {
		defer println(d) 
	}
}

Данная программа на языке Go выводит числа от 5 до 1. Причина этого заключается в использовании оператора `defer` внутри цикла `for`.

Оператор `defer` в Go откладывает выполнение функции до того момента, пока не завершится выполнение окружающей функции, в данном случае `main()`. Важно отметить, что отложенные вызовы выполняются в порядке LIFO (Last In, First Out), то есть последний отложенный вызов выполняется первым.

В цикле `for` переменная `d` последовательно принимает значения от 1 до 5. Каждый раз, когда цикл достигает оператора `defer`, вызов `println(d)` добавляется в стек отложенных вызовов. После завершения цикла, когда функция `main()` начинает завершаться, отложенные вызовы `println(d)` выполняются в обратном порядке: от последнего добавленного к первому. Таким образом, на экран выводятся числа 5, 4, 3, 2, 1.

2) Что выведет данная программа и почему?

package main

import (
	"fmt"
)

func main() {
	i := 0
	defer fmt.Println(i)
	i++
	return
}

В этом коде используется оператор defer, который откладывает выполнение функции до тех пор, пока не завершится окружающая функция (main в данном случае). Давайте разберем, что произойдет пошагово.

Код

package main

import (
	"fmt"
)

func main() {
	i := 0
	defer fmt.Println(i)
	i++
	return
}

Объяснение

  1. Инициализация переменной i:

    i := 0

    Переменная i инициализируется значением 0.

  2. Оператор defer:

    defer fmt.Println(i)

    Оператор defer откладывает выполнение функции fmt.Println(i) до тех пор, пока функция main не завершится. Важно отметить, что аргументы функции, переданной в defer, вычисляются сразу же, в момент вызова defer. Таким образом, в этот момент значение i равно 0, и именно это значение будет использовано при выполнении отложенной функции.

  3. Инкремент переменной i:

    i++

    Значение переменной i увеличивается на 1, и теперь i равно 1.

  4. Завершение функции main:

    return

    Функция main завершает выполнение. В этот момент выполняются все отложенные функции, в порядке, обратном их объявлению.

  5. Выполнение отложенной функции:

    fmt.Println(i)

    Отложенная функция fmt.Println(i) выполняется, используя значение i, которое было вычислено в момент вызова defer. Поскольку i было равно 0 в момент вызова defer, именно это значение будет напечатано.

Вывод

0

Заключение

  • Оператор defer откладывает выполнение функции до завершения окружающей функции.

  • Аргументы функции, переданной в defer, вычисляются сразу же в момент вызова defer.

  • В данном примере значение i было равно 0 в момент вызова defer, поэтому именно это значение будет напечатано, когда отложенная функция выполнится.

Last updated