«Это 19-й день моего участия в ноябрьском испытании обновлений. Подробную информацию об этом событии см.:Вызов последнего обновления 2021 г."
1 Что вы узнаете из этой главы?
- Что такое переменная? Зачем они нам нужны?
- Что такое тип?
- Как создавать переменные?
- Как присвоить значения переменным?
- Что такое константы? В чем разница между константой и переменной?
- Как определить константы?
- Как использовать константы?
2 охваченных технических концепции
- Переменная
- постоянный
- тип
- нетипизированная константа
3 Переменная — это место в памяти
Переменная — это пространство в памяти компьютера, которое может содержать часть данных, которые можно изменить. Слово «переменный» происходит от латинского «variabilis», что означает «изменчивый». В программе мы можем создавать переменные для хранения информации для последующего использования.
Например, если бы мы хотели записать количество гостей в отеле, «Количество гостей» было бы переменным числом. Мы можем создать переменные для хранения такой информации, как показано на рисунке:
4 Где хранятся переменные?
Ранее мы уже обсуждали ПЗУ, ОЗУ и дополнительное хранилище. Итак, где хранить переменные GO? Ответ прост, вы не можете выбирать, компилятор сделает это за вас!
5 Идентификатор переменной (имя переменной)
В большинстве языков программирования (и в Go) при создании переменной мы связываем ее сидентификаторСвязанный. Идентификатор — это «имя» переменной. Идентификатор — это «имя» переменной. Мы используем идентификаторы в программах для быстрого доступа к переменным. Идентификаторы состоят из букв и цифр. Идентификатор переменной будет использоваться внутри программы для указания хранящегося в ней значения. Идентификаторы должны быть краткими и описательными.
Для создания идентификаторов программисты могут указывать по своему усмотрению. Но они должны соблюдать эти простые правила:
- Идентификаторы могут состоять только из символов и цифр Unicode, таких как: 1,2,3, A, B, b, Ô...
- Идентификаторы должны начинаться с символа Unicode или символа подчеркивания «_», а не с цифры.
- Некоторые идентификаторы нельзя использовать, потому что они используются языком как зарезервированные слова.
Зарезервированные слова в Go: break, default, func, interface, select, case, defer, go, map, struct, chan, else, goto, package, switch, const, fallthrough, if, range, type, continue, for , импорт, возврат, вар
numberOfGuestsявляется действительным идентификатором переменной, который, в свою очередь,113Guestsнедопустимо, потому что оно начинается с цифры. На самом деле именование переменных — это тоже наука, и очень сложно придумать идентификаторы переменных, которые «видят имя и знают его значение».
6 основных типов
Мы можем хранить информацию в переменных. Но «информация» слишком широка, и мы должны быть более точными. Нужно ли хранить числа (1, 2000, 3), числа с плавающей запятой (2.45665), текст ("Комната 112 для некурящих")? нам нужнотипКонцепция, чтобы указать, какие значения могут быть присвоены переменным этого типа.
Язык Go предопределяет набор примитивных типов, которые вы можете сразу использовать в своей программе. Вы также можете определить свои типы (как мы увидим позже). Теперь давайте рассмотрим наиболее часто используемые типы:
- нить
- имя типа: строка
- Пример: "офис управления", "комната 265",...
- беззнаковое целое
- Имена типов: uint, uint8, uint16, uint32, uint64.
- Пример: 2445, 676, 0, 1, ...
- Целое число
- Имена типов: int, int8, int16, int32, int64
- Пример: -1245, 65, 78, ...
- логический тип
- имя типа: bool
- Пример: правда, ложь
- число с плавающей запятой
- Имена типов: float32, float64
- Пример: 12,67
6.1 О числах 8, 16, 32 и 64
Вы могли заметить, что у нас есть пять типов целых чисел: int, int8, int16, int32, int64. То же самое касается целых чисел без знака, у нас есть uint, uint8, uint16, uint32 и uint64. Варианты с плавающей запятой более ограничены: мы можем использовать float32 или float64.
Если вы хотите хранить числа без знака, вы можете использовать целые типы без знака. Вот 5 на выбор:
- uint8
- uint16
- uint32
- uint64
- uint
К каждому из них, кроме последнего, добавляется номер. Это число соответствует количеству битов памяти, выделенных для его хранения.
Если вы читали первую часть, то знаете:
- Имея 8 бит памяти, мы можем хранить десятичные числа от 0 до 2^{7}+2^{6}+...+2^{0}=2552 7 +2 6 +...+2 0 =255 .
- Используя 16 бит (2 байта), мы можем хранить от 0 до 2^{15}+2^{14}+...+2^{0}=65 535.
- Используя 32 бита (4 байта), мы можем хранить от 0 до 2^{31}+2^{30}+...+2^{0}=4 294 967 295.
- Используя 64 бита (8 байт), мы можем хранить от 0 до 2^{63}+2^{62}+...+2^{0}=18 446 744 073 709 551 615.
Вы можете заметить, что максимальное десятичное значение 64 бита очень велико. Помните! Если вам нужно хранить значения до 255, используйте uint8 вместо uint64. В противном случае вы потеряете место для хранения (поскольку вы будете использовать только 8 из 64 бит, выделенных в памяти!)
Последний типuint. Если вы используете этот тип в своей программе, память, выделенная для вашего целого числа без знака, будетКак минимумсоставляет 32 бита. В конечном счете, сколько битов будет зависеть от системы, в которой будет выполняться программа. Если это 32-битная система, это эквивалентно uint32. Если система 64-битная, тоuintЕмкость хранилища будет такой же, какuint64такой же. (Чтобы лучше понять разницу между 32-битной и 64-битной версиями, см. предыдущую главу)
7 Объявление переменной
Если вы хотите использовать переменную в своей программе, вам нужно сначала объявить ее.
7.1 Три действия, выполняемые при объявлении переменной
Когда вы объявляете переменную, она идет:
- будетидентификаторпривязать к переменной
- будеттиппривязать к переменной
- значение переменнойинициализациязатипизПо умолчанию
Когда вы определяете переменную и устанавливаете тип, Go инициализирует значение переменной типом по умолчанию.
7.2 Объявление переменной без инициализации
На изображении выше вы можете увидеть, как объявляются переменные. В первом примере мы объявили переменную типа int с именем roomNumber. Во втором мы объявляем две переменные в одной строке: roomNumber и floorNumber. Они имеют тип int. Их значение равно 0 (это нулевое значение типа int).
package main
import "fmt"
func main() {
var roomNumber, floorNumber int
fmt.Println(roomNumber, floorNumber)
var password string
fmt.Println(password)
}
Вывод программы:
0 0
Переменная строкового типаpasswordИнициализируется нулевым значением строкового типа, пустой строкой "". Переменные roomNumber и floorNumber инициализируются нулевым значением типа int, то есть 0.
Первая строка вывода программы является результатом fmt.Println(roomNumber,floorNumber). Вторая строка является результатом fmt.Println(пароль).
7.3 Объявление инициализированной переменной
Вы также можете объявить переменную и напрямую инициализировать ее значение. На приведенной выше диаграмме показан возможный синтаксис. Возьмем пример:
package main
import "fmt"
func main() {
var roomNumber, floorNumber int = 154, 3
fmt.Println(roomNumber, floorNumber)
var password = "notSecured"
fmt.Println(password)
}
В основной функции первый оператор объявляет две переменные roomNumber и floorNumber. Они имеют тип int и инициализируются значениями 154 и 3. Затем программа напечатает эти переменные.
Слева от знака равенства находится выражение или список выражений. Мы подробно рассмотрим выражения в другом разделе.
Затем мы определяем переменнуюpassword, мы инициализируем его значением «notSecured». Обратите внимание, что здесь не указан тип, Go присвоит тип инициализируемого значения переменной. Здесь тип «notSecured» — строка, поэтому переменнаяpasswordТип — строка.
7.4 Более короткие объявления переменных
Короткий синтаксис исключаетvarключевые слова,=символ заменен на:=. Вы также можете определить несколько переменных одновременно, используя этот синтаксис:
roomNumber := 154
Тип не указан явно, компилятор выведет его из выражения (или списка выражений).
Вот пример:
package main
import "fmt"
func main() {
roomNumber, floorNumber := 154, 3
fmt.Println(roomNumber, floorNumber)
}
Предупреждение: короткие объявления переменных нельзя использовать вне функций!
// will not compile
package main
vatRat := 20
func main(){
}
Предупреждение: вы не можете использовать значение nil для коротких объявлений переменных, компилятор не может определить тип переменной.
8 Что такое константа?
константа происходит от латинского слова «constare», что означает «стоять твердо». Константа — это значение в программе, которое остается неизменным и не изменяется во время выполнения. Переменная может измениться во время выполнения, константа не изменится, она останется неизменной.
Например, мы можем хранить в константе:
- версию нашей программы. Например: «1.3.2». Это значение останется стабильным во время работы программы. Мы изменим это значение при компиляции другой версии программы.
- Время сборки программы.
- Шаблоны электронной почты (если наше приложение не может быть настроено).
- Сообщение об ошибке.
В заключение, используйте постоянное хранилище, когда вы уверены, что вам никогда не потребуется изменять значение во время выполнения программы, константанеизменный. Константы бывают двух видов: типизированные и нетипизированные.
9 Типизированные константы
Это типизированная константа:
const version string = "1.3.2"
Ключевое слово const указывает компилятору, что мы собираемся определитьдовольно частоколичество. После ключевого слова const устанавливается идентификатор константы. В приведенном выше примере идентификатором является «версия». Типы четко определены (здесьнить) и значение константы (в виде выражения).
10 нетипизированных констант
Это нетипизированная константа:
const version = "1.3.2"
Нетипизированная константа:
- нет типа
- имеет значение по умолчанию
- безлимитный
10.1 Нетипизированная константа не имеет типа...
Приведите пример, иллюстрирующий первый пункт (нетипизированные константы не имеют типа)
package main
import "fmt"
func main() {
const occupancyLimit = 12
var occupancyLimit1 uint8
var occupancyLimit2 int64
var occupancyLimit3 float32
// assign our untyped const to an uint8 variable
occupancyLimit1 = occupancyLimit
// assign our untyped const to an int64 variable
occupancyLimit2 = occupancyLimit
// assign our untyped const to an float32 variable
occupancyLimit3 = occupancyLimit
fmt.Println(occupancyLimit1, occupancyLimit2, occupancyLimit3)
}
Вывод программы:
12 12 12
В этой программе мы сначала определяем нетипизированную константу с именем occupancyLimit и значением 12. Здесь константа не имеет определенного типа, но имеет целочисленное значение.
Затем определяем 3 переменные: occupancyLimit1, occupancyLimit2, occupancyLimit2 (типы этих переменных uint8, int64, float32).
Затем мы присваиваем этим переменным значение occupancyLimit. Наша программа компилируется, указывая, что значения наших констант можно помещать в переменные разных типов!
Если изменить значение occupancyLimit на 256, компиляция сообщит об ошибке, подумайте, почему?
10.2 ... но при необходимости с типами по умолчанию
Чтобы понять концепцию типов по умолчанию, давайте возьмем еще один пример.
package main
import "fmt"
func main() {
const occupancyLimit = 12
var occupancyLimit4 string
occupancyLimit4 = occupancyLimit
fmt.Println(occupancyLimit4)
}
В этой программе мы определяем константу occupancyLimit, значение которой равно 12 (целое число). Мы определяем переменную occupancyLimit4 типа string. Затем мы пытаемся присвоить значение константы occupancyLimit4. Мы пытаемся преобразовать целое число в строку. Будет ли компилироваться эта программа? Ответ - нет! Ошибка компиляции:
./main.go:10:19: cannot use occupancyLimit (type int) as type string in assignment
Нетипизированная константа имеет тип по умолчанию, который определяется значением, присвоенным ей во время компиляции. В нашем примере тип occupancyLimit по умолчанию — int. Целое число не может быть присвоено строковой переменной.
Тип нетипизированной константы по умолчанию:
- bool (логическое значение)
- rune
- int (целочисленное значение)
- float64 (значение с плавающей запятой)
- комплекс128 (комплексное значение)
- строка (строковое значение)
package main
func main() {
// default type is bool
const isOpen = true
// default type is rune (alias for int32)
const MyRune = 'r'
// default type is int
const occupancyLimit = 12
// default type is float64
const vatRate = 29.87
// default type is complex128
const complexNumber = 1 + 2i
// default type is string
const hotelName = "Gopher Hotel"
}
### 10.3 无类型常量没有限制
无类型常量在需要时没有类型和默认类型。无类型常量的值可能会溢出其默认类型。这样的常量没有类型;因此,它不依赖于任何类型限制。让我们举个例子:
```Go
package main
func main() {
// maximum value of an int is 9223372036854775807
// 9223372036854775808 (max + 1 ) overflows int
const profit = 9223372036854775808
// the program compiles
}
В этой программе мы создаем нетипизированную константу, называемую прибылью, и ее значение равно int64) Максимально допустимое значение: 9223372036854775807. Эта программа прекрасно компилируется. Но когда мы пытаемся присвоить это постоянное значение типизированной переменной, программа не компилируется. Продемонстрируем это на примере:
package main
import "fmt"
func main() {
// maximum value of an int is 9223372036854775807
// 9223372036854775808 (max + 1 ) overflows int
const profit = 9223372036854775808
var profit2 int64 = profit
fmt.Println(profit2)
}
В программе определена переменная profit2 типа int64. Затем мы пытаемся присвоить значение нетипизированной постоянной прибыли прибыли2.
Попробуем скомпилировать программу:
$ go build main.go
# command-line-arguments
./main.go:9:7: constant 9223372036854775808 overflows int64
Мы получаем ошибку компиляции, и это нормально. То, что мы пытаемся сделать, незаконно.
10.4 Зачем использовать константы
- Может улучшить читаемость вашей программы
При правильном выборе постоянные идентификаторы предоставят читателю больше информации, чем исходное значение. Сравнивать:
loc, err := time.LoadLocation(UKTimezoneName)
if err != nil {
return nil, err
}
loc, err := time.LoadLocation("Europe/London")
if err != nil {
return nil, err
}
Мы используем константу UKTimezoneName вместо исходного значения «Европа/Лондон». Мы скрываем сложность строк часового пояса от читателя. Также читатель поймет наш замысел: мы хотим загрузить локацию Великобритании.
- Вы предлагаете возможность заплатить эту стоимость (через другую программу или в вашей программе)
- Компилятор может улучшить сгенерированный машинный код. Вы говорите компилятору, что это значение никогда не изменится; если компилятор умен (а так оно и есть), он будет использовать его с умом.
11 Выберите идентификатор (имя переменной, имя константы)
Именование переменных и констант — непростая задача. Когда вы выбираете имя, вы должны убедиться, что выбранное имя предоставляет правильный объем информации о своем имени. Если вы выберете хорошее имя идентификатора, другие разработчики, работающие над тем же проектом, оценят его, потому что код будет легче читать. Когда мы говорим «отправьте правильное сообщение», слово «правильный» неоднозначно. Не существует научных правил именования программных структур. Даже без научных правил я могу дать вам несколько советов, которыми делится наше сообщество.
-
Избегайте однобуквенного имени: оно передает слишком мало информации о том, что хранится. Исключением является то, что счетчики обычно имеют имена k, i и j (внутри цикла мы вернемся к этому позже).
-
Используйте CamelCase: это хорошо зарекомендовавшее себя соглашение в сообществе Go. по сравнению с
occupancy_limitиoccupancy-limit,occupancyLimitлучше. -
не более двух слов
profitValueпросто хорошо,profitValueBeforeTaxMinusOperationalCostsСлишком длинное -
Избегайте упоминания типов в именах
descriptionStringфигово,descriptionдостоин выбора. Go уже статически типизирован, вам не нужно предоставлять информацию о типе читателю.
12 практических применений
12.1 Задачи
12.1.1 Программирование
Напишите программу, которая делает следующее:
- Создать
hotelNameи значение"Gopher Hotel"строковая константа - Создайте две нетипизированные константы, содержащие 24.806078 и -78.243027 соответственно. Имена этих двух констант
longitudeиlatitude. (где-то на Багамах) - Создать
occupancyизintВведите переменную с инициализированным значением 12. - Распечатать
hotelName,longitude,latitude, и вывести с новой строкиoccupancy.
12.1.2 Викторина с призами
-
longitudeиlatitudeКакой тип по умолчанию? -
latitudeЧто такое тип? - Переменная
occupancyдаintтип, это 64-битное, 32-битное или 8-битное целое число?
12.2 Справочные ответы
12.2.1 Программирование
package main
import "fmt"
func main() {
const hotelName string = "Gopher Hotel"
const longitude = 24.806078
const latitude = -78.243027
var occupancy int = 12
fmt.Println(hotelName, longitude, latitude)
fmt.Println(occupancy)
}
Начнем с констант типаhotelNameопределение иlongitudeиlatitude(нетипизированное) определение начинается. Затем мы определяем переменнуюoccupancy(Типы:int) и установите его значение равным 12. Обратите внимание, что возможен и другой синтаксис:
- короткое объявление переменной
occupancy := 12
- Типы могут быть опущены в стандартных объявлениях
var occupancy = 12
- Мы можем объявлять и назначать переменные в два шага
var occupancy int
occupancy = 12
12.2.2 Ответы на викторину
-
longitudeиlatitudeКакой тип по умолчанию? поплавок64 -
latitudeЧто такое тип? нет типа,latitudeТо же самое (они обе нетипизированные константы) - Переменная
occupancyдаintтип, это 64-битное, 32-битное или 8-битное целое число? Зависит от компьютера, на котором он был собран.int— это тип с размером, зависящим от реализации, на 32-битных машинах это будет 32-битное целое число (int32); на 64-битных машинах это будет 64-битное целое число (int64).
13 Тест в классе
13.1 Проблемы
- Что такое идентификатор?
- С какого символа должен начинаться идентификатор?
- Каков тип переменной?
- Что такое байты?
- Когда вы объявляете переменную типа bool, каково ее значение (после инициализации)?
- Каковы три основные характеристики нетипизированных констант?
13.2 Ответы
- Что такое идентификатор? Идентификатор — это набор букв и цифр, используемый для доступа к переменным в программе.
- С какого символа должен начинаться идентификатор? начинается с буквы или подчеркивания
- Каков тип переменной? Тип переменной — это набор допустимых значений переменных.
- Что такое байты? Байт состоит из 8 двоичных цифр
- Когда вы объявляете переменную типа bool, каково ее значение (после инициализации)? false, когда вы объявляете переменную, она инициализируется значением по умолчанию (нулевым значением) своего типа.
- Каковы три основные характеристики нетипизированных констант?
- нет типа
- имеет тип по умолчанию
- Неограничено (например: может переполнить максимальное целочисленное значение)
14 ключевых выводов
- Имя переменной или константы называется идентификатором.
- Идентификаторы обычно пишутся верблюжьим регистром.
- Переменные и константы позволяют хранить значение в памяти.
- Константы неизменяемы, что означает, что мы не можем изменить их значение во время выполнения программы.
- Переменные имеют тип, определяющий набор значений, которые они могут содержать.
- Когда вы создаете переменную, ее значение инициализируется нулевым значением ее типа.
- этот момент очень важен
- это может быть источником ошибки
- В Go нет неинициализированных переменных
- В Go есть два типа констант.
- типизированная константа
- нетипизированная константа нет типов, только тип по умолчанию, и может переполнять свой тип по умолчанию