Переменные являются важным понятием в программировании, которое необходимо освоить. Это символы, которые представляют значение, используемое в программе.
В этом руководстве будут рассмотрены основы переменных и лучшие практики их использования в программах на Go.
Понимание переменных
Технически переменная — это присвоение местоположения хранения значению, связанному с символическим именем или идентификатором. Мы используем имя переменной для ссылки на это сохраненное значение в компьютерной программе.
Можно представить переменную как ярлык с именем, который вы прикрепляете к значению.
Допустим, у нас есть целое число 1032049348
, и мы хотим сохранить его в переменной, а не постоянно переписывать это длинное число. Для этого мы можем использовать легко запоминающееся имя, например, переменную i
. Чтобы сохранить значение в переменной, мы используем следующий синтаксис:
Мы можем представить эту переменную как ярлык, который привязан к значению.
На ярлыке написано имя переменной i
, и он привязан к целочисленному значению 1032049348
.
Фраза i := 1032049348
— это оператор объявления и присваивания, состоящий из нескольких частей:
- имя переменной (
i
) - короткое объявление переменной с присваиванием (
:=
) - значение, которое присваивается имени переменной (
1032049348
) - тип данных, выводимый Go (
int
)
Мы увидим позже, как явно задать тип в следующем разделе.
Вместе эти части составляют оператор, который устанавливает переменную i
равной значению целого числа 1032049348
.
Как только мы присваиваем переменной значение, мы инициализируем или создаем эту переменную. После этого мы готовы использовать переменную вместо значения.
После того как мы установили i
равным значению 1032049348
, мы можем использовать i
вместо целого числа, так что давайте выведем его:
Output1032049348
Мы также можем быстро и легко выполнять математические операции, используя переменные. С i := 1032049348
мы можем вычесть целочисленное значение 813
с помощью следующего синтаксиса:
Output1032048535
В этом примере Go выполняет вычисления за нас, вычитая 813 из переменной i
и возвращая сумму 1032048535
.
Говоря о математике, переменные могут быть установлены равными результату математического уравнения. Вы также можете сложить два числа и сохранить значение суммы в переменной x
:
Возможно, вы заметили, что этот пример похож на алгебру. Так же, как мы используем буквы и другие символы для представления чисел и величин в формулах и уравнениях, переменные являются символическими именами, представляющими значение типа данных. Для правильного синтаксиса Go вам нужно убедиться, что ваша переменная находится слева от любого уравнения.
Давайте выведем x
:
Output221
Go вернул значение 221
, потому что переменная x
была установлена равной сумме 76
и 145
.
Переменные могут представлять любой тип данных, не только целые числа:
Если вы выведете любую из этих переменных, Go вернет то, чему эта переменная эквивалентна. Давайте рассмотрим оператор присваивания для строкового типа данных slice
:
Output[one two three]
Мы присвоили значение среза []string{"one", "two", "three"}
переменной slice
, а затем использовали функцию fmt.Println
для вывода этого значения, вызвав slice
.
Переменные работают, выделяя небольшую область памяти в вашем компьютере, которая принимает указанные значения, а затем связывается с этим пространством.
Объявление переменных
В Go существует несколько способов объявить переменную, и в некоторых случаях более одного способа объявить одну и ту же переменную и значение.
Мы можем объявить переменную с именем i
типа данных int
без инициализации. Это означает, что мы объявим пространство для размещения значения, но не зададим ему начальное значение:
Это создает переменную, объявленную как i
типа данных int
.
Мы можем инициализировать значение с помощью оператора равенства (=
), как в следующем примере:
В Go оба этих вида объявления называются длинными объявлениями переменных.
Мы также можем использовать короткое объявление переменной:
В этом случае у нас есть переменная с именем i
и типом данных int
. Когда мы не указываем тип данных, Go самостоятельно определит его.
С тремя способами объявления переменных сообщество Go приняло следующие идиомы:
-
Используйте длинную форму,
var i int
, только когда вы не инициализируете переменную. -
Используйте короткую форму,
i := 1
, при объявлении и инициализации. -
Если вы не хотите, чтобы Go определял тип данных, но все еще хотите использовать короткое объявление переменной, вы можете обернуть свое значение в желаемый тип с помощью следующего синтаксиса:
Использование длинной формы объявления переменной при инициализации значения не считается идиоматичным в Go:
Хорошей практикой является следование тому, как обычно объявляют переменные в сообществе Go, чтобы другие могли легко читать ваши программы.
Нулевые значения
Все встроенные типы имеют нулевое значение. Любая выделенная переменная может быть использована, даже если ей никогда не было присвоено значение. Мы можем увидеть нулевые значения для следующих типов:
Outputvar a int = 0
var b string = ""
var c float64 = 0
var d bool = false
Мы использовали глагол %T
в операторе fmt.Printf
. Это говорит функции печатать тип данных
для переменной.
В Go, поскольку все значения имеют нулевое
значение, мы не можем иметь неопределенные
значения, как в некоторых других языках. Например, логический
тип в некоторых языках может быть неопределенным
, истинным
или ложным
, что позволяет переменной иметь три
состояния. В Go мы не можем иметь более двух
состояний для логического значения.
Именование переменных: правила и стиль
Именование переменных довольно гибкое, но есть некоторые правила, о которых стоит помнить:
- Имена переменных должны состоять только из одного слова (без пробелов).
- Имена переменных должны состоять только из букв, цифр и подчеркиваний (
_
). - Имена переменных не могут начинаться с цифры.
Следуя этим правилам, давайте рассмотрим как корректные, так и некорректные имена переменных:
Valid | Invalid | Why Invalid |
---|---|---|
userName |
user-name |
Hyphens are not permitted |
name4 |
4name |
Cannot begin with a number |
user |
$user |
Cannot use symbols |
userName |
user name |
Cannot be more than one word |
Кроме того, помните, что имена переменных чувствительны к регистру. Эти имена userName
, USERNAME
, UserName
и uSERnAME
являются полностью разными переменными. Лучше избегать использования похожих имен переменных в программе, чтобы обеспечить понимание их назначения как вам, так и вашим соавторам — как текущим, так и будущим.
Хотя переменные чувствительны к регистру, регистр первой буквы переменной имеет особое значение в Go. Если переменная начинается с заглавной буквы, то она доступна за пределами пакета, в котором была объявлена (или экспортирована
). Если переменная начинается с строчной буквы, то она доступна только внутри пакета, в котором объявлена.
Email
начинается с заглавной буквы и может быть доступен другими пакетами. password
начинается со строчной буквы и доступен только внутри пакета, в котором объявлен.
В Go принято использовать очень краткие (или короткие) имена переменных. Выбирая между userName
и user
для переменной, идиоматично выбрать user
.
Область видимости также влияет на краткость имени переменной. Правило таково: чем меньше область видимости переменной, тем короче должно быть её имя:
Мы используем переменную names
в более широкой области видимости, поэтому обычно ей дают более осмысленное имя, чтобы помочь запомнить, что она означает в программе. Однако переменные i
и n
мы используем сразу в следующей строке кода, а затем больше их не используем… По этой причине это не запутает читателя кода относительно того, где используются переменные, или что они означают.
Далее, давайте рассмотрим некоторые заметки о стиле переменных. Стиль заключается в использовании MixedCaps
или mixedCaps
вместо подчеркиваний для имен из нескольких слов.
Conventional Style | Unconventional Style | Why Unconventional |
---|---|---|
userName |
user_name |
Underscores are not conventional |
i |
index |
prefer i over index as it is shorter |
serveHTTP |
serveHttp |
acronyms should be capitalized |
Самое важное в стиле — быть последовательным, и чтобы команда, с которой вы работаете, согласилась с этим стилем.
Переназначение переменных
Как следует из слова “переменная”, мы можем легко изменять переменные в Go. Это означает, что мы можем связать другое значение с ранее назначенной переменной через переназначение. Возможность переназначения полезна, потому что на протяжении всей программы нам может понадобиться принимать значения, сгенерированные пользователем, в уже инициализированные переменные. Нам также может понадобиться изменить назначение на что-то, что было определено ранее.
Зная, что мы можем легко переназначить переменную, может быть полезно при работе над большой программой, написанной кем-то другим, и не ясно, какие переменные уже определены.
Давайте присвоим значение 76
переменной с именем i
типа int
, а затем присвоим ей новое значение 42
:
Output76
42
Этот пример показывает, что мы можем сначала присвоить переменной i
значение целого числа, а затем переназначить переменную i
, присвоив ей на этот раз значение 42
.
Примечание: При объявлении и инициализации переменной можно использовать :=
, однако, когда вы хотите просто изменить значение уже объявленной переменной, достаточно использовать оператор равенства (=
).
Поскольку Go является типизированным
языком, мы не можем присваивать один тип другому. Например, мы не можем присвоить значение "Sammy"
переменной типа int
:
Пытаясь присвоить друг другу разные типы, мы получим ошибку компиляции:
Outputcannot use "Sammy" (type string) as type int in assignment
Go не позволит нам использовать имя переменной более одного раза:
Outputs redeclared in this block
Если мы попытаемся использовать короткое объявление переменной более одного раза для одного и того же имени переменной, мы также получим ошибку компиляции. Это может произойти случайно, поэтому понимание того, что означает сообщение об ошибке, полезно:
Outputno new variables on left side of :=
Так же, как и при объявлении переменной, учет её именования улучшит читаемость вашей программы для вас и других, когда вы вернетесь к ней в будущем.
Множественное присваивание
Go также позволяет нам присваивать несколько значений нескольким переменным в одной строке. Каждое из этих значений может быть разного типа:
Outputshark
2.05
15
В этом примере переменной j
была присвоена строка "shark"
, переменной k
было присвоено значение с плавающей точкой 2.05
, а переменной l
было присвоено целочисленное значение 15
.
Такой подход к присваиванию нескольких переменных нескольким значениям в одной строке может сократить количество строк в вашем коде. Однако важно не жертвовать читаемостью ради меньшего количества строк кода.
Глобальные и локальные переменные
При использовании переменных в программе важно учитывать область видимости переменной. Область видимости переменной относится к конкретным местам, откуда она доступна в коде заданной программы. Это означает, что не все переменные доступны из всех частей заданной программы — некоторые переменные будут глобальными, а некоторые — локальными.
Глобальные переменные существуют вне функций. Локальные переменные существуют внутри функций.
Рассмотрим глобальные и локальные переменные на практике:
Outputlocal
global
Здесь мы используем var g = "global"
для создания глобальной переменной вне функции. Затем мы определяем функцию printLocal()
. Внутри функции присваивается локальная переменная с именем l
и затем выводится. Программа завершается вызовом printLocal()
и последующим выводом глобальной переменной g
.
Поскольку g
является глобальной переменной, мы можем ссылаться на неё в printLocal()
. Давайте модифицируем предыдущую программу, чтобы это сделать:
Outputlocal
global
global
Мы начинаем с объявления глобальной переменной g
, var g = "global"
. В функции main
мы вызываем функцию printLocal
, которая объявляет локальную переменную l
и выводит её, fmt.Println(l)
. Затем printLocal
выводит глобальную переменную g
, fmt.Println(g)
. Несмотря на то, что g
не была определена внутри printLocal
, к ней всё равно можно было получить доступ, поскольку она была объявлена в глобальной области видимости. Наконец, функция main
также выводит g
.
Теперь попробуем вызвать локальную переменную вне функции:
Outputundefined: l
Мы не можем использовать локальную переменную вне функции, в которой она была присвоена. Если вы попытаетесь это сделать, вы получите ошибку undefined
при компиляции.
Рассмотрим другой пример, где мы используем одно и то же имя переменной для глобальной и локальной переменной:
Output10
7
5
В этой программе мы объявили переменную num1
дважды. Во-первых, мы объявили num1
в глобальной области видимости, var num1 = 5
, и снова в локальной области видимости функции printNumbers
, num1 := 10
. Когда мы выводим num1
из программы main
, мы видим, что выводится значение 5
. Это происходит потому, что main
видит только глобальное объявление переменной. Однако, когда мы выводим num1
из функции printNumbers
, она видит локальное объявление и выводит значение 10
. Несмотря на то, что printNumbers
создает новую переменную с именем num1
и присваивает ей значение 10
, это не влияет на глобальный экземпляр num1
со значением 5
.
При работе с переменными также необходимо учитывать, какие части вашей программы будут нуждаться в доступе к каждой из переменных; соответственно выбирая глобальные или локальные переменные. В программах на Go вы обнаружите, что локальные переменные обычно встречаются чаще.
Константы
Константы похожи на переменные, за исключением того, что их нельзя изменить после объявления. Константы полезны для определения значения, которое будет использоваться более одного раза в вашей программе, но не должно изменяться.
Например, если бы мы хотели объявить ставку налога для системы корзины покупок, мы могли бы использовать константу, а затем рассчитывать налог в разных областях нашей программы. В какой-то момент в будущем, если ставка налога изменится, нам нужно будет изменить это значение только в одном месте нашей программы. Если бы мы использовали переменную, возможно, что мы могли бы случайно изменить её значение где-то в нашей программе, что привело бы к неправильному расчёту.
Для объявления константы мы можем использовать следующий синтаксис:
OutputSammy
Если мы попытаемся изменить константу после её объявления, мы получим ошибку времени компиляции:
Outputcannot assign to shark
Константы могут быть untyped
. Это может быть полезно при работе с числами, такими как данные целочисленного типа. Если константа untyped
, она явно преобразуется, в то время как typed
константы не преобразуются. Давайте посмотрим, как мы можем использовать константы:
Output8760
21900
21960
Если вы объявляете константу с типом, она будет именно этим типом. Здесь, когда мы объявляем константу leapYear
, мы определяем её как тип данных int32
. Поэтому это typed
константа, что означает, что она может работать только с данными типа int32
. Константа year
, которую мы объявляем без типа, поэтому она считается untyped
. Из-за этого вы можете использовать её с любым целым типом данных.
Когда hours
было определено, оно вывело тип int
, потому что мы не указали его явно, hours := 24
. Когда мы объявили minutes
, мы явно указали его как int32
, minutes := int32(60)
.
Теперь давайте рассмотрим каждый расчёт и почему он работает:
В этом случае hours
является int
, а years
— нетипизированным. Когда программа компилируется, она явно преобразует years
в int
, что позволяет успешно выполнить операцию умножения.
В этом случае minutes
является int32
, а year
— нетипизированным. Когда программа компилируется, она явно преобразует years
в int32
, что позволяет успешно выполнить операцию умножения.
В этом случае minutes
является int32
, а leapYear
— типизированной константой типа int32
. На этот раз компилятору нечего делать, так как обе переменные уже имеют один и тот же тип.
Если мы попытаемся умножить два типа, которые являются типизированными
и несовместимыми, программа не скомпилируется:
Outputinvalid operation: hours * leapYear (mismatched types int and int32)
В этом случае hours
был выведен как int
, а leapYear
был явно объявлен как int32
. Поскольку Go — типизированный язык, int
и int32
несовместимы для математических операций. Чтобы их умножить, вам нужно преобразовать один в int32
или int
.
Заключение
В этом уроке мы рассмотрели некоторые из распространенных вариантов использования переменных в Go. Переменные являются важным строительным блоком программирования, выступая в качестве символов, которые заменяют значение типа данных, используемого в программе.
Source:
https://www.digitalocean.com/community/tutorials/how-to-use-variables-and-constants-in-go