Управление потоком

Эта глава посвящена логике программы. Без управляющих конструкций ваш код был бы просто списком команд, выполняющихся один раз. Управляющие конструкции позволяют нам сворачивать код в циклы и принимать решения на ходу.

До этого момента наши программы напоминали простой список покупок: они выполнялись строго сверху вниз по одному разу. Но что, если нам нужно вывести числа от 1 до 100? Писать fmt.Println сто раз — плохая затея. Нам нужны инструменты для повторения действий и принятия решений.

Цикл For

В Go есть только один цикл — for. Но он настолько универсален, что заменяет собой while, do-while и foreach из других языков.

Вариант 1: Цикл с условием (аналог while)

package main
import "fmt"

func main() {
    i := 1
    for i <= 10 {
        fmt.Println(i)
        i = i + 1
    }
}

Здесь цикл работает, пока условие истинно (true). Как только станет равно 11, выполнение прекратится.

Вариант 2: Классический цикл

Это наиболее частая форма записи, где все части собраны в одну строку:

for i := 1; i <= 10; i++ {
    fmt.Println(i)
}

  1. i := 1 — инициализация (выполняется один раз).
  2. i <= 10 — условие (проверяется перед каждой итерацией).
  3. i++ — действие после итерации (увеличение на 1).

Вариант 3: Бесконечный цикл

Если убрать все условия, цикл будет работать вечно, пока вы не остановите его вручную (например, через break или завершение программы):

for {
    fmt.Println("Я работаю вечно")
}


Условный оператор If

Оператор if позволяет выполнять код только в том случае, если условие истинно.

if i % 2 == 0 {
    fmt.Println("Число четное")
} else {
    fmt.Println("Число нечетное")
}

Оператор % (остаток от деления) — незаменимый инструмент. Если , значит, число делится на 2 без остатка.

Идиома Go: If с короткой декларацией

В Go принято ограничивать область видимости переменных. Вы можете объявить переменную прямо в условии if:

if length := len(name); length > 10 {
    fmt.Println("Слишком длинное имя")
}
// Переменная length здесь уже не существует

Это «чистый» стиль Go, который вы будете встречать в 90% случаев при обработке ошибок.


Оператор Switch

Когда условий else if становится слишком много, код превращается в «лесенку», которую трудно читать. В этом случае лучше использовать switch.

switch i {
case 0: fmt.Println("Ноль")
case 1: fmt.Println("Один")
case 2: fmt.Println("Два")
default: fmt.Println("Неизвестное число")
}

Особенности Switch в Go:

  1. Нет автоматического проваливания: В отличие от C++ или Java, в Go не нужно писать break после каждого case. Выполнится только один подходящий блок.
  2. Множественные значения: Можно написать case 1, 2, 3:, если для этих чисел нужно выполнить одно и то же действие.
  3. Switch без выражения: Если написать просто switch { ... }, он будет работать как большая связка if-else, где в каждом case можно писать сложные условия (например, case i > 10 && i < 20:).

Задачи

  • Чтение кода: Что выведет эта программа? ```go i := 10 if i > 10 { fmt.Println(“Big”) } else { fmt.Println(“Small”) }


* [ ] **Деление на 3:** Напишите программу, которая выводит все числа от 1 до 100, кратные 3 (3, 6, 9...).
* [ ] **FizzBuzz (Классика):** Напишите программу, которая выводит числа от 1 до 100. Но:
* Для чисел, кратных 3, вместо числа выведите «Fizz».
* Для чисел, кратных 5, выведите «Buzz».
* Для чисел, кратных и 3, и 5, выведите «FizzBuzz».



---

## Полезные ссылки

1. [A Tour of Go: Flow Control](https://go.dev/tour/flowcontrol/1) — интерактивные упражнения по циклам и условиям.
2. [Go by Example: If/Else](https://gobyexample.com/if-else) и [Switch](https://gobyexample.com/switch).
3. [Effective Go: Control Structures](https://www.google.com/search?q=https://go.dev/doc/effective_go%23control_structures) — более глубокий разбор логики Go.

---