> For the complete documentation index, see [llms.txt](https://yuliyas-organization-3.gitbook.io/prokhodim-sobesedovanie-na-golang-razrabotchika/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yuliyas-organization-3.gitbook.io/prokhodim-sobesedovanie-na-golang-razrabotchika/golang-zadachi/zadachi-na-defer.md).

# Задачи на defer

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

```go
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) Что выведет данная программа и почему?

```go
package main

import (
	"fmt"
)

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

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

#### Код

```go
package main

import (
	"fmt"
)

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

#### Объяснение

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

   ```go
   i := 0
   ```

   Переменная `i` инициализируется значением `0`.
2. **Оператор `defer`**:

   ```go
   defer fmt.Println(i)
   ```

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

   ```go
   i++
   ```

   Значение переменной `i` увеличивается на `1`, и теперь `i` равно `1`.
4. **Завершение функции `main`**:

   ```go
   return
   ```

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

   ```go
   fmt.Println(i)
   ```

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

#### Вывод

```
0
```

#### Заключение

* Оператор `defer` откладывает выполнение функции до завершения окружающей функции.
* Аргументы функции, переданной в `defer`, вычисляются сразу же в момент вызова `defer`.
* В данном примере значение `i` было равно `0` в момент вызова `defer`, поэтому именно это значение будет напечатано, когда отложенная функция выполнится.

\ <br>
