Типы данных в Go
Go (Golang) — многопоточный язык программирования, разработанный в 2009 году компанией Google. Он создан с целью упростить написание высокоэффективного ПО, а его синтаксис схож с языком Си.
В настоящей инструкции рассмотрим различные типы данных в Go, а также предложим рекомендации по их выбору.
Объявление переменных
Объявление переменной — это процесс ее создания и назначения ей имени и типа данных. В Go переменные могут быть объявлены с помощью ключевого слова var
, а также с помощью оператора :=
.
Синтаксис объявления переменных с использованием var
:
var variable_name data_type
А вот так выглядит объявление переменных через var
:
var FirstName string
var salary float32
Теперь рассмотрим второй способ объявления переменных, а именно с инициализацией, т.е. с указанием начального значения при их создании.
Синтаксис объявления переменных с инициализацией выглядит следующим образом:
var variable_name data_type = value
А вот так выглядит объявление на примерах:
var FirstName string = "Ilya"
var salary float32 = 35000
Кроме всего перечисленного, существует краткий способ объявления переменных с помощью оператора :=
. Данный способ автоматически задает тип переменной при указании значения. Синтаксис:
variable_name := initial_value
Примеры:
FirstName := "Ilya"
salary := 35000
Как видно по картинке ниже, переменной FirstName
автоматически присваивается тип string
, а переменной salary
— int
.
Основные типы данных
В первую очередь, обратим внимание на основные типы данных.
Целочисленные типы данных
Целочисленные типы данных в Go описывают целочисленные значения, которые могут быть положительными, отрицательными или нулевыми. В Go существует несколько типов целочисленных данных, которые отличаются друг от друга размером в байтах. Рассмотрим каждый из них подробнее в таблице ниже.
Тип |
Описание |
Диапазон чисел |
int8 |
8-битные числа со знаком. |
от -128 до 127 |
int16 |
16-битные числа со знаком. |
от -32,768 до 32,767 |
int32 |
32-битные числа со знаком. |
от -231 до 231-1 |
int64 |
64-битные числа со знаком. |
от -263 до 263-1 |
int |
Представляет собой 32-битные или 64-битные числа со знаком (в зависимости от платформы). Он используется для работы с целочисленными значениями по умолчанию. |
Как у int32 или int64 (в зависимости от платформы) |
uint8 |
8-битные числа без знака. |
от 0 до 255 |
uint16 |
16-битные числа без знака. |
от 0 до 65,535 |
uint32 |
32-битные числа без знака. |
от 0 до 232-1 |
uint64 |
64-битные числа без знака. |
от 0 до 264-1 |
uint |
Представляет собой 32-битные или 64-битные числа без знака (в зависимости от платформы). |
Как у uint32 или uint64 (в зависимости от платформы) |
Кроме перечисленных, еще есть byte
и rune
. Они эквиваленты uint8
и int32
соответственно.
Примеры объявления целочисленных переменных:
var x int16 = 45000
var y uint = 73000
var z byte = 4
Вещественные типы данных
Вещественные типы данных используются для хранения дробных чисел. В Go предложено 2 варианта: float32
и float64
.
float32
занимает 4 байта в памяти и может хранить числа с плавающей точкой от-3.4028235E+38
до3.4028235E+38
с точностью до 7 знаков после запятой;float64
занимает 8 байт в памяти и может хранить числа с плавающей точкой от-1.7976931348623157E+308
до1.7976931348623157E+308
с точностью до 15 знаков после запятой.
Важно понимать, что вещественные числа в компьютере представлены в двоичной форме, и поэтому могут быть неточными. Это может приводить к ошибкам округления при выполнении операций с такими числами. Поэтому при работе с ними важно учитывать особенности их представления в компьютере и принимать меры для избежания ошибок округления.
Примеры объявления вещественных переменных:
var x float32 = 3.14
var y float64 = 3.1415926535897
Строковые типы данных
Строковые типы данных в Go используются для хранения символьных строк. Каждый символ строки представляет собой последовательность байтов в памяти.
Строки являются неизменяемыми (immutable
) объектами в Go. Это означает, что после создания строки ее содержимое не может быть изменено. Однако, можно создать новую строку, объединив несколько существующих строк.
В Go также имеются специальные символы. Некоторые из них представлены ниже:
\n
— перевод строки.\t
— табуляция.\"
— двойная кавычка.\'
— одинарная кавычка.\\
— обратный слеш.
Кроме того, существует возможность использовать Unicode-символы. Для этого можно использовать последовательность символов в формате \uXXXX
, где XXXX — это шестнадцатеричное значение Unicode-кода символа.
Примеры объявления строковой переменной:
var exampleText1 string = "Hello, user1!"
exampleText2 := "Hello, user2!"
Логический тип данных
В Go есть логический тип данных bool
, который может принимать значения true
и false
.
Данный тип данных может использоваться для хранения значений логических выражений, например, в условных операторах if
и switch
, а также в логических операциях, таких как &&
(логическое И), ||
(логическое ИЛИ) и !
(логическое НЕ).
Например, мы можем использовать логический тип данных в следующем коде:
age := 18
isAdult := age >= 18
fmt.Println(isAdult)
Результат выполнения кода показан на картинке ниже.
Составные типы данных
Далее рассмотрим составные типы в Go.
Массивы
Массивы в Go применяются для хранения фиксированного количества элементов одного типа. Главное отличие от других языков в том, что здесь массивы являются значениями, а не ссылками на данные.
Для определения массива необходимо указать тип элемента и количество элементов в квадратных скобках. Например:
var exampleArr [4]int = [4]int{2, 5, 7, 9}
Доступ к элементам массива осуществляется по индексу, начиная с 0:
fmt.Println(exampleArr[0])
Массивы в Go также поддерживают итерацию с помощью цикла for:
for i := 0; i < len(exampleArr); i++ {
fmt.Println(exampleArr[i])
}
Подробнее о циклах for
в языке Go мы писали в этой статье.
Срезы
Срезы (Slices
) в Go — это ссылочный тип данных, который представляет собой динамический массив элементов, хранящихся в памяти. Они очень похожи на массивы, но в отличие от них, их размер может корректироваться во время выполнения программы, а также они являются ссылками на данные, а не значениями.
Определение среза осуществляется с помощью следующей синтаксической конструкции:
var slice []T
Где T
— тип элементов среза, а slice
— переменная, хранящая ссылку на срез.
Пустой срез может быть объявлен так:
emptySlice := []int{}
Для инициализации среза можно использовать функцию make
, которая создает новый срез заданной длины:
slice := make([]int, 5)
В примере выше создается срез пяти элементов типа int
.
Чтобы получить доступ к элементам используется индексация, также как и с массивами.
Структуры
Вкратце, структуры — это набор полей. Поля в свою очередь характеризуют различные атрибуты объектов.
Для объявления структуры в Go используется ключевое слово type
, далее указывается имя структуры и ее определение в фигурных скобках. Например, ниже в примере объявим структуру, представляющую информацию о человеке:
type Person struct {
Name string
Age int
Address string
}
Для создания переменной, хранящей значения структуры, нужно использовать ключевое слово var и имя переменной. Затем после имени переменной следует имя структуры, за которым следует фигурные скобки со значениями полей структуры в виде имя_поля: значение
. Например:
var person1 Person
person1 = Person{Name: "John", Age: 30, Address: "123 Main St."}
Здесь мы объявляем переменную person1
типа Person
и присваиваем ей значения для каждого поля. Можно также использовать короткую форму инициализации структуры:
person2 := Person{Name: "Jane", Age: 25, Address: "456 Elm St."}
Доступ к полям структуры осуществляется с помощью оператора точки (.
). Например, чтобы получить имя person1
, нужно написать:
person1.Name
Структуры могут содержать внутри себя другие структуры и даже ссылки на самих себя (так называемые рекурсивные структуры). Кроме того, они могут реализовывать интерфейсы.
Карты
Карта (map
) является ссылочным типом данных, который используется для представления неупорядоченного набора пар ключ-значение. Ключи в карте должны быть уникальными, но значения могут повторяться.
Чтобы создать карту, используется встроенная функция make()
, которой передаются типы ключа и значения. Следующий код создает пустую карту с ключами string
и значениями int
:
m := make(map[string]int)
Чтобы добавить элемент в карту, можно использовать следующую форму записи:
m[key] = value
Где key
— ключ элемента, а value
— значение элемента. Например:
m["apple"] = 3
m["banana"] = 5
Чтобы получить значение элемента по ключу, используется следующая форма записи:
value := m[key]
Например, для получения значения элемента с ключом apple
:
count := m["apple"]
Если элемента с указанным ключом нет в карте, то будет возвращено значение по умолчанию.
Чтобы удалить элемент из карты, можно использовать встроенную функцию delete()
. Следующий код удаляет элемент с ключом apple
:
delete(m, "apple")
В Go карты реализованы в виде хеш-таблиц, поэтому порядок элементов в карте не фиксирован и может меняться при каждом выполнении программы. Также следует обратить внимание на то, что карта не является потокобезопасной, поэтому при параллельном доступе к карте необходимо воспользоваться механизмами синхронизации доступа (мьютексы или каналы).
Указатели и интерфейсы
Указатели
Указатели необходимы для взаимодействия с переменными, хранящими адреса в памяти. Они могут быть определены с помощью символа &
перед переменной, а для получения значения, на которое указывает указатель, используется символ *
.
Пример:
var myInt int = 42
var myIntPointer *int = &myInt
fmt.Println(*myIntPointer)
Вывод программы показан на картинке ниже.
Интерфейсы
Интерфейсы служат для определения набора методов, которые должен реализовать тип данных. Интерфейсы могут быть использованы для абстрагирования от конкретного типа данных и для реализации полиморфизма. Чтобы создать интерфейс в Go необходимо определить набор методов, которые должен реализовать тип данных.
Пример:
type Writer interface {
Write([]byte) (int, error)
}
Здесь определяется интерфейс Writer
, который должен иметь метод Write
с аргументом типа []byte
и возвращающий количество записанных байтов и ошибку.
Заключение
В данной инструкции мы рассмотрели основные типы данных в Go. Кроме того, для каждого из них мы привели синтаксис объявления и рабочие примеры.
Надеемся, данная инструкция и советы в ней помогут вам научиться правильно выбирать типы данных в своем коде, что приведет к улучшению производительности разрабатываемых программ.