Перейти к содержанию
Educora
Начальный14 мин3 / 10

Условия, циклы и switch

Принимай решения с помощью `if` и инструкции инициализации, изучи все формы `for` — единственного цикла Go — и `switch` без `break`.

Проверь себя
В этом уроке ты узнаешь
  • Писать if, else if и if с инструкцией инициализации
  • Использовать классическую, условную, бесконечную форму for и форму с range
  • Работать со switch, fallthrough и break с меткой

Приложение погоды смотрит на температуру и пишет «жарко» или «холодно», а игра повторяет одни и те же шаги, пока игрок не победит. Чтобы программа принимала решения и повторяла действия, нужны условия и циклы. В Go для этого всего три инструмента — if, for и switch, и каждый из них настолько же мощный, насколько простой.

if, else и инструкция инициализации

В Go условие не берут в круглые скобки, зато фигурные скобки обязательны даже для блока из одной строки. С помощью else if можно проверить сколько угодно условий. Особая возможность: перед условием можно написать короткую инструкцию инициализации и точку с запятой, например if n, err := strconv.Atoi(s); err == nil. Созданные в ней переменные видны только внутри блоков if и else.

Go
package main

import (
	"fmt"
	"strconv"
)

func main() {
	temperature := 28
	if temperature > 30 {
		fmt.Println("Hot")
	} else if temperature > 20 {
		fmt.Println("Warm")
	} else {
		fmt.Println("Cold")
	}

	if n, err := strconv.Atoi("17"); err == nil {
		fmt.Println("double:", n*2)
	}
	if _, err := strconv.Atoi("abc"); err != nil {
		fmt.Println("error:", err)
	}
}
Ожидаемый результат
Warm
double: 34
error: strconv.Atoi: parsing "abc": invalid syntax

В условиях используют операторы сравнения (==, !=, <, >, <=, >=) и логические операторы: && (и), || (или), ! (не). В Go условие обязано быть bool: написать if n, как в C, нельзя — нужно if n != 0.

for — единственный цикл

В Go нет while и do-while: все циклы записываются через for. Но у for несколько форм, и он заменяет все циклы других языков. break прерывает цикл, а continue пропускает остаток текущего шага и переходит к следующему.

ФормаПримерВ других языках
Классическаяfor i := 0; i < 5; i++ { }for в C и Java
Только условиеfor n < 100 { }while
Бесконечнаяfor { ... break }while (true)
С rangefor i, v := range items { }for-each
По числу (Go 1.22+)for i := range 5 { }range(5) в Python
Go
package main

import "fmt"

func main() {
	for i := 1; i <= 3; i++ {
		fmt.Println("step", i)
	}

	n := 1
	for n < 100 {
		n *= 3
	}
	fmt.Println("n =", n)

	for i := range 5 {
		if i%2 == 0 {
			continue
		}
		fmt.Println("odd:", i)
	}

	for i, r := range "Gəncə" {
		fmt.Println(i, string(r))
	}
}
Ожидаемый результат
step 1
step 2
step 3
n = 243
odd: 1
odd: 3
0 G
1 ə
3 n
4 c
5 ə

Условный цикл умножает n на 3, пока оно не превысит 100: 1 → 3 → 9 → 27 → 81 → 243. Теперь посмотри на последний цикл: range проходит по строке символами (рунами), а не байтами, а i — это индекс байта, с которого начинается символ. Так как ə занимает два байта, индекс перескакивает с 1 сразу на 3. Если индекс не нужен, пиши на его месте _: for _, r := range s.

switch

switch сравнивает значение с несколькими вариантами. В отличие от Java и C, в Go не нужно писать break в конце каждого case: выполняется подходящий блок, и switch завершается. В одном case можно перечислить несколько значений через запятую. А switch без выражения заменяет длинную цепочку if-else: в каждом case записывается своё условие.

Go
package main

import "fmt"

func main() {
	day := "Saturday"
	switch day {
	case "Saturday", "Sunday":
		fmt.Println("Weekend")
	default:
		fmt.Println("Weekday")
	}

	score := 83
	switch {
	case score >= 90:
		fmt.Println("Excellent")
	case score >= 75:
		fmt.Println("Good")
	default:
		fmt.Println("Keep going")
	}

	switch n := 2; n {
	case 2:
		fmt.Println("two")
		fallthrough
	case 3:
		fmt.Println("three")
	case 4:
		fmt.Println("four")
	}
}
Ожидаемый результат
Weekend
Good
two
three

Как и if, switch принимает инструкцию инициализации: switch n := 2; n. А ключевое слово fallthrough выполняет и блок следующего case, не проверяя его условие, поэтому в примере после two напечаталось и three. В реальном коде оно нужно очень редко.

Длинная цепочка if-else
if score >= 90 {
	grade = "A"
} else if score >= 75 {
	grade = "B"
} else if score >= 50 {
	grade = "C"
} else {
	grade = "F"
}
switch без выражения
switch {
case score >= 90:
	grade = "A"
case score >= 75:
	grade = "B"
case score >= 50:
	grade = "C"
default:
	grade = "F"
}
Оба варианта делают одно и то же, но при большом числе условий switch читается аккуратнее. Варианты case проверяются сверху вниз, и срабатывает первое истинное условие.
Go
package main

import "fmt"

func main() {
	commands := []string{"move", "jump", "stop", "move"}
loop:
	for _, c := range commands {
		switch c {
		case "stop":
			break loop
		default:
			fmt.Println("doing", c)
		}
	}
	fmt.Println("finished")
}
Ожидаемый результат
doing move
doing jump
finished
[]string{...} — это срез (список) строк; срезы ты изучишь в отдельном уроке.

Главное

  • В if условие пишется без скобок, а {} обязательны; инструкция инициализации (if x := f(); x > 0) ограничивает переменную блоком.
  • for — единственный цикл в Go: у него есть классическая, условная, бесконечная форма и форма с range.
  • range проходит по строке символами и даёт индексы байтов; for i := range n работает начиная с Go 1.22.
  • В switch не пишут break; в case может быть несколько значений, а switch без выражения заменяет цепочку if-else.
  • Чтобы прервать весь цикл из вложенного в него switch, нужен break с меткой.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
Как в Go записать то, что в других языках называют циклом while?