Истории успеха наших клиентов — лучшие проекты
Вход/ Регистрация

Переменные в Go и работа с ними

1568
20 минут чтения
Средний рейтинг статьи: 4

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

Язык программирования 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:

    

Консольный вывод этого примера будет следующим:

    

Переменные в строке

Часто необходимо вставить переменную в строку. Сделать это можно несколькими способами:

    

В консоли появится следующий вывод:

    

Также можно комбинировать числовые переменные со строковыми:

    

В этом случае вывод будет таким:

    

Подготовили для вас выгодные тарифы на облачные серверы

Cloud MSK 15

477 ₽/мес

Процессор
1 x 3.3 ГГц
Память
1 ГБ
NVMe
15 ГБ
Канал
1 Гбит/с
Публичный IP
Cloud MSK 30

657 ₽/мес

Процессор
1 x 3.3 ГГц
Память
2 ГБ
NVMe
30 ГБ
Канал
1 Гбит/с
Публичный IP

Заключение

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

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

В этом руководстве мы рассмотрели только базовые способы работы с переменными. Более подробную (и исчерпывающую) информацию о типах и их особенностях можно узнать в официальной документации Golang.

Дополнительно, в официальном каталоге пакетного менеджера Go можно найти информацию о множестве полезных модулей, доступных для импорта в проект. Одним из таких модулей, например, является «Стандартная библиотека»

1568
20 минут чтения
Средний рейтинг статьи: 4
Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server