Инициализация в if
В прошлом уроке программа выбирала дорогу на развилке по указателю. Иногда перед развилкой нужно сначала что-то узнать: например, посмотреть на небо и только потом читать указатель про дождь. Это наблюдение нужно только на этой развилке, дальше по дороге оно ни к чему.
Переменную, нужную только для одной проверки, можно объявить перед if. Но тогда она остаётся в программе до конца main:
package main
import "fmt"
func main() {
n := 2023
r := n % 4
if r == 0 {
fmt.Println("divisible by 4")
} else {
fmt.Println("remainder", r) // remainder 3
}
}Давайте разберём программу по строкам:
n := 2023объявляет год.r := n % 4кладёт вrостаток от деления2023на4, то есть3.if r == 0— условие ложно, поэтому выполняется веткаelseи печатаетremainder 3.
После if остаток r больше не нужен, но имя занято до конца функции. Ниже его можно по ошибке использовать снова, думая, что в нём что-то другое.
Инструкция перед условием
Перед условием if можно написать короткую инструкцию и отделить её точкой с запятой. Такую инструкцию называют инициализацией. Заголовок if с ней состоит из четырёх частей:
- ключевое слово
if; - инициализация, например
r := n % 4; - точка с запятой;
- условие, например
r == 0.
Вот та же программа с инициализацией:
n := 2023
if r := n % 4; r == 0 {
fmt.Println("divisible by 4")
} else {
fmt.Println("remainder", r) // remainder 3
}Давайте разберём, в каком порядке всё выполняется:
- Сначала Go выполняет инициализацию
r := n % 4и кладёт3вr. - Затем Go проверяет условие
r == 0. Оно ложно. - Ветка
elseпечатает остаток:remainder 3.
Инициализация выполняется один раз, сколько бы веток ни было.
Что пишут в инициализации
Инициализация бывает разной. Разберём три случая.
Объявление через :=
Чаще всего в инициализации объявляют переменную через :=, как r := n % 4 выше. Так объявляют значение, которое нужно только для проверки и внутри веток.
Вызов функции
В инициализации можно вызвать и функцию. Запись if s := add(2, 3); s > 4 { сохраняет результат вызова в s и сразу его проверяет.
Так результат не нужно хранить в отдельной переменной перед if, и он не занимает имя в остальной функции.
Своя инициализация у else if
У else if может быть своя инициализация, тоже через точку с запятой перед условием. Её переменная видна в этой ветке и в следующих за ней, но не в предыдущих.
Где видна переменная
Область видимости переменной — часть программы, в которой к ней можно обратиться по имени. Переменная из инициализации видна:
- в условии;
- в блоке
if; - в каждом
else if; - в
else.
Область видимости заканчивается вместе с последней веткой. Внутри веток переменную можно читать и менять, как любую другую. После закрывающей скобки последней ветки её уже нет, и имя r не мешает остальному коду функции.
Нажмите «Следующий шаг» и следите за r в рамке main: когда она появляется и когда исчезает.
1–4package main · import "fmt"5func main() {6 n := 20237 if r := n % 4; r == 0 {8 fmt.Println("divisible by 4")9 } else {10 fmt.Println("remainder", r)11 }12}
n := 2023 объявляет год.
Здесь аналогия с наблюдением перед развилкой расходится с Go. Человек помнит погоду и после развилки, а переменная из инициализации после if исчезает совсем. На собеседовании иногда показывают код, который обращается к такой переменной после if, и спрашивают, что произойдёт.
Частая ошибка
К переменной из инициализации обратились после if:
n := 2023
if r := n % 4; r == 0 {
fmt.Println("divisible by 4")
}
fmt.Println(r) // ✗undefined: rОшибка указывает на строку с fmt.Println(r), а не на if.
Программа не компилируется: за пределами if переменной r нет, а другой переменной с таким именем в main не объявлено. Если значение нужно и после if, объявите переменную перед ним, как в первой программе.
Главное
- Перед условием
ifможно написать инициализацию:if r := n % 4; r == 0 {. - Инициализация выполняется один раз, до проверки условия.
- Переменная из инициализации видна в условии и во всех ветках, но не после
if. - Если значение нужно и после
if, объявите переменную перед ним.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.