Область видимости переменных в Golang

Под конец данного урока вы сможете:

  • Оценить преимущества области видимости переменных;
  • Использовать краткий способ объявления переменных;
  • Посмотреть, как область видимости переменных взаимодействует с for, if и switch;
  • Выбрать узкую или широкую область видимости для рассматриваемого случая.

По ходу выполнения программы многие переменные немного используются на протяжении довольно короткого времени, после чего сбрасываются. Это обусловлено правилами видимости языка.

Форум Гоферов

Мы работаем над форумом для программистов на Golang. Очень нужны модераторы которые хотят помочь с ответами для новичков и помочь в развитии Go-сообщества.

Go на Форум

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК Go в Telegram

Содержание статьи

Как много информации человек может запомнить за один раз? Было сделано предположение, что наша кратковременная память ограничена семью объектами. Хорошим примером данной концепции является семизначный номер телефона.

Компьютеры могут хранить довольно много значений в своей краткосрочной памяти или Random-access memory (RAM), однако нужно помнить, что код читается не только компьютерами, но и людьми. Поэтому очень важно, чтобы код оставался максимально простым и понятным.

Если бы можно было изменить переменную в любое время или получить к ней доступ откуда бы то ни было, тогда большая программа очень быстро стала бы очень беспорядочной. Область видимости переменных помогает сфокусироваться на уместных для рассматриваемой функции или участка кода переменных без необходимости заботиться об оставшейся части.

Область видимости переменных в Golang

Когда переменная объявляется, она попадает в область видимости. Проще говоря, переменная становится видимой. Если переменная находится в области видимости, тогда программа всегда может получить к ней доступ. Однако, как только переменная покидает область видимости, при попытке получить к ней доступ выйдет ошибка.

Преимущество области видимости в том, что вы можете повторно использовать одно и то же название для разных переменных. Представьте программу, в которой у каждой переменной должно быть уникальное название. Теперь попробуйте представить программу в несколько раз больше.

При чтении кода область видимости очень помогает, потому что пропадает необходимость запоминать все переменные. Как только переменная выходит из области видимости, можно больше не думать о ней.

В Go область видимости начинает и заканчивается фигурными скобками {}. В следующей программе функция main начинает область видимости, а вместе с циклом for стартует вложенная область.

Переменная count объявляется внутри области видимости функции, она видима до конца функции main, в то время как переменная num объявляется внутри области видимости цикла for. По завершении цикла переменная num выходит из области видимости.

При попытке получить доступ к переменной num после цикла, компилятор Go выведет ошибку. Однако получить доступ к переменной count по завершении цикла for все еще можно, ведь ее объявили за пределами цикла, хотя особой причины для этого не было. Для заключения переменной count в области видимости цикла понадобится использовать другой способ объявления переменных Go.

Вопросы для проверки:

  1. В чем преимущество области видимости переменных?
  2. Что случится с переменной, когда она покинет область видимости? Измените код предыдущего примера кода для получения доступа к num после цикла и посмотрите, что произойдет.

Краткое объявление переменных в Go

Краткое объявление переменной осуществляется через альтернативный синтаксис для ключевого слова var. Следующие две строки эквивалентны:

Поначалу может показаться, что разница невелика, однако разница в три символа делает сокращенный вариант намного популярнее способа с var. Кроме того, краткое объявление может использоваться в некоторых местах, где недопустимо ключевое слово var.

В следующей программе показан пример цикла for, что совмещает инициализацию, условие и последующий оператор, что уменьшает значение count. При использовании данной формы цикла for очень важен порядок: инициализация, условие, операция.

Не используя краткое объявление, переменную count нужно было бы объявить за пределами цикла, следовательно, переменная в таком случае после завершения цикла остается в области видимости.

В следующей программе при задействовании краткого объявления, переменная count объявляется и инициализируется как часть цикла for, по завершении цикла выходит из области видимости. Если бы к переменной count доступ был получен за пределами цикла, тогда компилятор Go выдал бы ошибку undefined: count.

Краткое объявление дает возможность объявить новую переменную в операторе if. В следующем коде переменная num может использовать в любом ответвлении оператора if.

Краткое объявление может использоваться с оператором switch, как показано в следующей программе:

Вопрос для проверки:

Как бы изменилась область видимости переменной num, если бы в предыдущих примерах не использовалось краткое объявление?

Узкая и широкая область видимости

Следующий код генерирует и отображает случайную дату — к примеру, дату вылета на Марс. В нем также представлено несколько областей видимости и показано, почему особенно важно задуматься об области видимости во время объявления переменной.

Переменная era объявляется за пределами функции main области видимости пакета. Если бы в пакете main использовалось несколько функций, тогда переменная era была бы видна для них всех.

На заметку: Краткое объявление недоступно для переменных, объявленных в области видимости пакета, поэтому переменную era нельзя объявить через era := "AD" в ее текущей позиции.

Переменная year видна только внутри функции main. Другие функции видят era, но не year. Область видимости функции уже, чем область видимости пакета. Она начинается c ключевого слова func и заканчивается закрывающей скобкой.

Переменная month доступна внутри оператора switch, но как только оператор switch заканчивается, month выводится из области видимости. Область видимости начинается с ключевого слова switch и заканчивается закрывающей скобкой switch.

У каждого case есть собственная область видимости и три независимые переменные day. Как только каждый случай заканчивается, объявленная внутри case переменная day выходит за пределы области видимости. Это единственная ситуация, когда для обозначения области видимости не используются скобки.

Код примера не идеален. Узкая область видимости переменных month и day приводит к дубликату кода (Println, Println, Println). Когда код дублируется, кто-то может пересмотреть код в одной области, но не в другой (при решений не выводить era, но забыв изменить один case). Иногда дублированный код имеет смысл, однако чаше всего он рассматривается как код с запашком и указывается на возможные проблемы в программе.

Для удаления дубликатов и упрощения кода переменные нужно было объявлять в более широкой области видимости функции, делая их доступными после оператора switch для дальнейшей работы.

Время рефакторинга! Рефакторинг предполагает модификацию кода без изменения его поведения. Следующая программа по-прежнему выводит случайную дату.

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

Вопрос для проверки:

Как можно распознать слишком узкую область видимости переменных?

Заключение

  • Открывающая фигурная скобка { вводит новую область видимости, что оканчивается закрывающей скобкой };
  • Ключевые слова case и default также вводят новую область видимости, хотя фигурные скобки здесь уже не используются;
  • Место объявления переменной определяется тем, в какой она области видимости;
  • Переменные, объявленные на той же строке, что и ключевые слова for, if или switch находятся в области видимости до окончания данного оператора;
  • Иногда широкая область видимости лучше, а иногда — узкая, все зависит от ситуации.

Задание для итоговой проверки:

Измените следующую программу для обработки високосных годов. Код должен:

  • Генерировать случайный год вместо постоянного использования 2018;
  • Для февраля присвойте daysInMonth на 29 для високосных годов, и 28 для всех остальных. Можете использовать оператор if вместо блока case;
  • Используйте цикл for для генерации и отображения 10 случайных дат.

Программа для модификации:

Понравилась статья?

Поддержи наш проект, чтобы мы могли создать больше хорошего контента!