Основы констант в Go

GolangBeginner
Практиковаться сейчас

Введение

На предыдущих занятиях мы познакомились с переменными в Go. В этом уроке мы изучим концепцию констант, способы их использования и разберемся, почему они так важны. Давайте погрузимся в мир констант.

Основные темы:

  • Что такое константы
  • Объявление констант
  • Генератор констант iota
  • Использование констант

Что такое константы?

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

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

Константы полезны, когда нужно зафиксировать значение, которое должно оставаться неизменным, например, адрес веб-сайта или математическую константу, такую как число π.

Объявление констант

Объявление констант очень похоже на объявление переменных, только вместо ключевого слова var используется const.

Примечание: Константе должно быть присвоено значение непосредственно при объявлении.

В Go все переменные обязательно должны быть использованы после определения, но константы являются исключением. Даже если вы их не используете, компилятор не выдаст ошибку.

Синтаксис объявления константы выглядит следующим образом:

const name [type] = value

Здесь name — это имя константы, type — тип данных (его можно опустить, так как Go умеет выводить тип автоматически), а value — присваиваемое значение.

Обратите внимание, что для объявления констант можно использовать только следующие типы:

  • Целочисленные типы
  • Типы с плавающей точкой
  • Комплексные типы
  • Логический тип (Boolean)
  • Строковый тип

Рассмотрим пример. Создайте новый файл с именем const.go в директории ~/project:

touch ~/project/const.go

Введите следующий код в файл const.go:

package main

import "fmt"

// Объявление одиночной константы
const labex string = "LabEx" // явное указание типа string
const labs = "LABS"    // тип string выводится компилятором автоматически

// Объявление группы констант
const (
    hangzhou, chengdu = "HANGZHOU", "CHENGDU"
    monday, tuesday, wednesday = "MONDAY", "TUESDAY", "WEDNESDAY"
)

func main() {
    fmt.Printf("The type of labex is: %T, and its value is %s\n", labex, labex)
    fmt.Printf("The type of labs is: %T, and its value is %s\n", labs, labs)

    fmt.Println()

    fmt.Println(hangzhou, chengdu)
    fmt.Println(monday, tuesday, wednesday)
}

Запустите программу:

go run ~/project/const.go

После выполнения вы увидите следующий результат:

The type of labex is: string, and its value is LabEx
The type of labs is: string, and its value is LABS

HANGZHOU CHENGDU
MONDAY TUESDAY WEDNESDAY

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

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

При объявлении группы констант в скобках действует интересное правило: если константе не присвоено значение, она наследует значение предыдущей константы.

Обновите код в const.go следующим образом:

package main

import "fmt"

const (
    monday    = "MONDAY"
    tuesday   = "TUESDAY"
    wednesday = "WEDNESDAY"
    thursday
    friday
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

Запустите программу:

go run ~/project/const.go

Результат будет таким:

MONDAY TUESDAY WEDNESDAY WEDNESDAY WEDNESDAY

Здесь для thursday и friday значения не указаны явно. Согласно правилам Go, они наследуют значение предыдущей константы. В данном случае:

  • thursday берет значение wednesday.
  • friday также берет значение wednesday.

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

Если вы хотите, чтобы thursday и friday имели свои собственные значения, их нужно указать явно:

const (
    monday    = "MONDAY"
    tuesday   = "TUESDAY"
    wednesday = "WEDNESDAY"
    thursday  = "THURSDAY"
    friday    = "FRIDAY"
)

Теперь результат будет соответствовать ожиданиям:

MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY

Генератор констант iota

Помимо ручного объявления, в Go есть удобный инструмент iota для создания последовательностей констант. Рассмотрим пример. Запишите следующий код в файл const.go:

package main

import "fmt"

const (
    monday    = iota // начальное значение 0
    tuesday   = iota // увеличивается на 1 каждый раз
    wednesday = iota
    thursday  = iota
    friday    = iota
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

Запустите программу:

go run ~/project/const.go

Результат:

0 1 2 3 4

При использовании iota начальное значение равно 0, и оно автоматически увеличивается на 1 для каждой последующей строки в блоке const.

После объявления первого элемента с iota, в последующих строках его можно не писать — Go поймет это автоматически:

package main

import "fmt"

const (
    monday    = iota // 0
    tuesday          // 1
    wednesday        // 2
    thursday         // 3
    friday           // 4
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

Что если нужно пропустить определенное значение? Для этого используется символ подчеркивания _ (пустой идентификатор). В следующем примере мы пропустим значение для среды:

package main

import "fmt"

const (
    monday  = iota // 0
    tuesday        // 1
    _
    thursday // 3
    friday   // 4
)

func main() {
    fmt.Println(monday, tuesday, thursday, friday)
}

Запустите программу:

go run ~/project/const.go

Как видите, результат будет таким:

0 1 3 4

Оператор iota также можно использовать в арифметических выражениях. Введите следующий код в const.go:

package main

import "fmt"

const (
    a = iota     // 0
    b = iota * 3 // 1 * 3
    c = iota + 4 // 2 + 4
)

const (
    B  = 1 << (iota * 10) // равно 1 << (0 * 10)
    KB                    // 1024
    MB                    // 1048576
)

func main() {
    fmt.Println(a, b, c)
    fmt.Println(B, KB, MB)
}

Запустите программу:

go run ~/project/const.go

Результат:

0 3 6
1 1024 1048576

В первом блоке мы использовали iota для простых арифметических операций.

Во втором блоке мы применили iota вместе с оператором побитового сдвига влево <<, чтобы выразить значения 1 KB и 1 MB через байты (B). Например, 1 KB равен 1024B, а 1 MB равен 1024 * 1024, что составляет 1048576B.

Проверка знаний

Теперь давайте закрепим пройденный материал. Создайте новый файл iota.go и с помощью iota и констант выведите значения 1 ГБ (GB) и 1 ТБ (TB) в байтах (B).

Требования:

  1. Не выводите готовые числа напрямую. Используйте iota для вычислений.
  2. Файл iota.go должен находиться в директории ~/project.

Подсказка: Вы можете опираться на пример из раздела про iota.

Ожидаемый формат вывода:

1GB is equal to 1073741824B
1TB is equal to 1099511627776B

Резюме

Давайте подведем итоги того, что мы изучили в этом уроке:

  • Константы нельзя изменить после их объявления.
  • Для создания констант используется ключевое слово const.
  • При объявлении группы констант предпочтительно использовать круглые скобки.
  • Генератор iota позволяет удобно создавать последовательности значений.
  • iota можно комбинировать с арифметическими и побитовыми операциями.

В этом уроке мы познакомились с константами и изучили работу генератора iota. Строки, целые числа, числа с плавающей точкой и константы составляют основу типов данных в Go.

✨ Проверить решение и практиковаться