Переменные — это именованные значения, которые хранятся в определенных областях оперативной памяти и используются во время выполнения программы.
Язык программирования Go (или Golang) основан на статической типизации. Это значит, что тип уже объявленной переменной константен и изменить его нельзя.
Сами переменные могут быть различных типов — каждый имеет свое предназначение и особенности.
В Golang есть несколько базовых типов данных, на основе которых строится логика работы программы:
- Целочисленный
- Вещественный
- Строковый
- Логический
Также есть и составные типы данных:
- Массивы
- Срезы
- Структуры
- Карты
А еще несколько вспомогательных типов:
- Указатели
- Интерфейсы
Помимо этого Golang (как, например, и C++) имеет «Стандартную библиотеку» (std), в которой содержится множество пользовательских типов.
Более подробно о типах переменных в Go можно узнать из отдельной статьи в официальном блоге Timeweb Cloud.
О том, как установить Golang на операционные системы Linux, Windows или macOS, можно почитать в отдельных руководствах Timeweb Cloud. Во всех показанных примерах использовался интерпретатор Golang версии 1.21.3.
VDS и VPS
биллингом по всему миру: Россия, Азия и Европа.
Компиляция и запуск кода
Все примеры кода, показанные в этом руководстве, запускаются в отдельных файлах с расширением .go.
Сперва создается:
Далее наполняется содержимым в виде кода внутри функции main() с подключением всех необходимых модулей:
После чего запускается:
Объявление переменной
Существует градация вариантов того, как объявить переменную в Go, прежде чем ее использовать — от полной формы с явным указанием параметров переменной (или нескольких переменных) до краткой формы с автоопределением объявления и автовыводом типа.
Использование каждой из форм объявления переменной зависит от контекста. Тем не менее, наиболее краткую и наиболее автоматическую запись рекомендуется использовать как можно чаще — она позволяет переложить часть ответственности на интерпретатор языка, тем самым снизив количество возможных ошибок по вине программиста.
Ключевое слово var
Наиболее явная форма объявления переменной в языке программирования Go предполагает указание ключевого слова var, имени переменной, ее типа и значения:
Однако при указании значения переменной явное указание типа можно опустить:
При этом переменную можно объявить без присваивания значения, но в этом случае требуется указать тип:
some_variable = 5
Во всех этих примерах:
- var — ключевое слово объявления переменной
- some_variable — произвольное имя переменной
- int — тип переменной
- 5 — значение переменной
Например, вот так можно объявлять переменные строкового типа:
А вот такое объявление переменной вызовет ошибку:
Важно помнить, что автовывод типа возможен только в момент объявления переменной, когда интерпретатор выделяет соответствующий объем оперативной памяти под ее значения.
Короткая форма :=
Несмотря на строгую статическую типизацию, Golang позволяет объявлять переменные в более лаконичной форме без явного указания ее параметров:
В этом случае интерпретатор понимает, что необходимо автоматически вывести тип переменной исходя из указанного значения.
Тем не менее, подобное объявление возможно только внутри функции (в том числе main()) — вне функции его использовать нельзя:
При этом важно понимать отличие объявление переменной (вместе с инициализацией) от присвоения значения:
Например, можно последовательно объявить (и инициализировать) несколько переменных:
При этом оператор := нельзя использовать вместе с ключевым словом var. Если это сделать, возникнет ошибка:
Исключение ключевого слова var, но с явным указанием типа по прежнему вызывает ошибку:
Несколько переменных
В языке программирования Go можно объявить сразу несколько переменных в одной строке или блоке.
Например, можно использовать ключевое слово var с указанием единого типа для всех объявляемых переменных:
Можно также разделить объявление переменных и присваивание значений:
Если типы переменных разные, то интерпретатор может вывести их типы автоматически:
Аналогично можно использовать краткую форму для нескольких переменных:
В этом случае нет ни ключевого слова var, не указанных типов переменных.
Еще один способ множественного объявления переменных — использование блока:
Кстати, блочное объявление можно отформатировать с помощью пробелов таким образом, чтобы имена, типы и значения выстраивались в несколько колонок, тем самым улучшая читаемость кода:
У блочного объявления переменных нет какого-либо утилитарного смысла. Это просто синтаксический сахар, который:
- Улучшает читабельность кода, собирая важные переменные в одном месте.
- Улучшает чистоту кода, исключая многократное использования ключевого слова var для каждой переменной.
- Улучшает поддерживаемость кода, упрощая поиск и внесение изменений в параметры переменных.
Таким образом, объявление в блоке оправдано только в тех случаях, когда необходимо сгруппировать несколько ключевых переменных, упростив их визуальное восприятие в текстовом редакторе кода.
Отсутствие инициализации
Создание переменной Go возможно без ее инициализации. В этом случае переменной будет присвоено нулевое значение, соответствующее указанному типу:
- Для
int,float32,float64— 0, 0.0, 0.0 - Для
bool— false - Для
string— "" - Для указателя — nil
Эту особенность того, как Go обрабатывает объявление и инициализацию переменных, можно рассмотреть на примере реального скрипта:
Консольный вывод будет таким:
Как видно, переменные разных типов автоматически инициализируются нулевыми (или пустыми) значениями там, где это возможно.
Стили именования
В языке программирования Go имена переменных могут начинаться либо с латинской буквы, либо с символа нижнего подчеркивания (_):
При этом у имени переменной есть одна функциональная особенность: имена, начинающиеся с заглавной буквы, видны в других пакетах, а начинающиеся с маленькой буквы — нет.
Существует также несколько способов именования переменных, которые можно считать общими для всех языков программирования, в том числе и для Go:
- Snake Case
- Camel Case
- Pascal Case
- Kebab Case (не поддерживается в Go)
При использовании Snake Case имя переменной выглядит так:
При использовании Camel Case имя переменной выглядит так:
При использовании Pascal Case имя переменной выглядит так:
При использовании Kebab Case имя переменной выглядит так:
Однако последний стиль именования переменных (Kebab Case) не поддерживается в языке Go из-за символа тире, который зарезервирован под операцию вычитания.
ПРИМЕР: Объявление множества переменных
Все показанные выше способы объявления переменных в языке программирования Go можно рассмотреть конкретнее на примере еще одного скрипта:
Результатом работы этого кода станет следующий вывод в консольном терминале:
Таким образом:
- Использование ключевого слова
varнеобходимо для явного объявления переменной, особенно в глобальной области видимости. - Использование оператора
:=необходимо для краткого объявления переменной, особенно внутри функций. - Использование блока
()необходимо для читабельного объявления целого множества переменных.
При этом надо помнить, что в языке программирования Go предпочтительнее минимализм и лаконичность форм записи. Поэтому наиболее краткая форма записи должна использоваться везде, где это возможно.
Все это позволяет снизить количество ошибок и сбоев, а также помогает поддерживать чистоту и читаемость кода.
Инициализация переменной
Как правило во время объявления переменной она вручную инициализируется каким-либо значением. При этом инициализация разных типов имеет синтаксические различия.
Число
Числовые переменные инициализируются присваиванием числового значения, что синтаксически выглядит тривиально:
Число можно инициализировать другим числом:
Строка
Строковые переменные инициализируются присваиванием последовательности символов, заключенных в двойные кавычки:
Строку можно также инициализировать другой строкой:
Булев
Инициализация булевых переменных ничем не отличается от инициализации числовых и строковых переменных за исключением того, что в качестве значения используется ключевое слово:
Аналогично, булевые переменные можно инициализировать другими булевыми переменными
Массив
Есть несколько способов инициализации массива. Самый простой — с помощью поочередного доступа к элементам:
Более сложный — через так называемый композитный литерал.
Композитный литерал — компактная синтаксическая конструкция для инициализации любого композитного (составного) типа, исключающая последовательное присваивание каждого элемента.
Таким образом массив можно инициализировать целиком за один шаг:
Или использовать краткую форму:
Также инициализировать элементы массива можно частично:
А с помощью такой записи инициализацию большого массива можно сделать более читабельной:
Кстати, массив можно инициализировать другим массивом, скопировав все его элементы:
При этом важно понимать, что копирование массива также выполняется при его передаче в функцию:
Вывод в консольный терминал будет следующим:
Таким образом изменениям подверглась только копия массива внутри функции change(), а не оригинальный массив из функции main().
Тем не менее, явная инициализация массива другим массивом возможна только в том случае, если оба массива имеют одинаковую длину и тип:
Помимо этого, в языке Go можно создавать массивы из произвольного числа других массивов. При этом, инициализировать элементы таких массивов можно как последовательно:
Так и с помощью композитного литерала:
Как видно, второй вариант занимает меньше места, но синтаксически более сложен.
Срез
Срез инициализируется также, как и массив:
Однако в отличие от массива, срез можно инициализировать другим срезом произвольной длины:
Карта
Карты инициализируются через композитный литерал с указанием типа ключа и значения. Содержимое же перечисляется через запятую, разделяясь двоеточием:
Можно также использовать короткую форму объявления и более читабельный вид инициализации:
При этом инициализация карты другой картой не копирует элементы, а делает их общими:
Консольный вывод этого примера будет таким:
Как можно заметить, любое изменение в одной из карт влияет также на другую.
Указатель
Указатели можно инициализировать только адресом переменной такого же типа:
Символ амперсанда (&) позволяет получить адрес любой переменной:
Консольный вывод этого примера будет примерно таким:
Для инициализации указателей можно также использовать краткую запись:
Для того, чтобы получить значение по адресу указателя, его нужно разыменовать с помощью символа звездочки (*):
В этом случае в терминале консоли появится такой вывод:
Таким образом можно присваивать новые значения переменной, расположенной по адресу указателя:
В консоли появится такой вывод:
Наконец, указатель можно инициализировать безымянным объектом в памяти. Для этого используется функция new(), которая возвращает адрес выделенной области памяти:
Удалять же выделенную область памяти вручную не надо — этим автоматически занимается сборщик мусора.
Структура
Структуру можно инициализировать либо последовательно указанными значениями:
Либо значениями, указанными явно по ключам:
А можно вообще не указывать никаких значений, тем самым автоматически инициализировать все нулями:
В этом случае консольный вывод будет таким:
Ветвление на основе переменных
Переменные занимают центральное место в ветвлениях. На основе их значений (по условию) выполняются различные участки кода программы.
if/else
Самая базовая условная конструкция создается операторами if/else. Так выглядит наиболее простое условие:
Например, с помощью простого условия можно проверить указатель:
Более сложная форма описывается так:
А с помощью комбинации else и if можно создавать еще более сложные конструкции:
При этом выражений if/else может быть несколько:
switch
Еще один способ ветвления — конструкция switch, внутри которой задаются возможные значения переменной и действия, которые нужно выполнить, если есть совпадение:
С помощью секции default можно задать действие, выполняющееся при отсутствии совпадений:
Можно также объединить несколько возможных совпадений внутри одной секции:
Полезные функции
В языке Go есть множество дополнительных функций для работы с переменными. В этом руководстве мы рассмотрим лишь основные из них.
Переменные окружения
В языке Go есть специальные системные функции, позволяющие как установить переменную окружения, так и получить ее значение:
Переменная времени
Часто логика программы требует измерения времени. В языке Go для этого есть соответствующий инструмент — переменная типа time.
Надо сказать, что время — это отдельная обширная тема. Узнать же больше о пакете time можно в официальной документации.
В этом же руководстве будет показано, как узнать текущее время в различных форматах:
В консольном терминале появится следующий вывод:
Можно также уточнить конкретный параметр времени:
В этом случае консольный вывод будет таким:
Добавление и удаление элементов среза
К срезам можно добавлять элементы:
Или удалять элементы из них:
Удаление в данном случае выполняется с помощью оператора среза, который создает из одной последовательности другую.
В консольном терминале будет следующий вывод:
Проверка типа переменной
Тип переменной можно узнать с помощью функции TypeOf(), которая содержится в модуле reflect:
Консольный вывод этого примера будет следующим:
Переменные в строке
Часто необходимо вставить переменную в строку. Сделать это можно несколькими способами:
В консоли появится следующий вывод:
Также можно комбинировать числовые переменные со строковыми:
В этом случае вывод будет таким:
Подготовили для вас выгодные тарифы на облачные серверы
477 ₽/мес
657 ₽/мес
Заключение
Переменные в Go, как и в большинстве других языков программирования, необходимы для хранения данных.
Так как данные отличаются друг от друга, переменные Go обладают несколькими базовыми типами — каждый из них имеет особое представление в оперативной памяти компьютера.
В этом руководстве мы рассмотрели только базовые способы работы с переменными. Более подробную (и исчерпывающую) информацию о типах и их особенностях можно узнать в официальной документации Golang.
Дополнительно, в официальном каталоге пакетного менеджера Go можно найти информацию о множестве полезных модулей, доступных для импорта в проект. Одним из таких модулей, например, является «Стандартная библиотека»
