Язык#Go следует минималистичному подходу к системе типов, поэтому базовых типов не так много.
Типы в официальной спецификации.
Целые числа
Для представления целочисленных переменных в Go есть ряд типов, различающихся лишь размерностью и отсутствием или наличием знака в них:
- знаковые:
int
,int8
,int16
,int32
,int64
; - беззнаковые:
uint
,uint8
,uint16
,uint32
,uint64
.
Если размерности int64
недостаточно, можно воспользоваться типом big.Int
из пакета math/big
.
Спецификация языка Go гарантирует реализацию всех специфицированных типов на всех заявленных платформах. То есть, на 32-битных системах можно использовать тип int64
.
Числа с плавающей точкой
Числа с плавающей точкой представлены в двух вариантах: комплексные и вещественные. Как и у целочисленных типов, у них есть разные размерности:
- комплексные:
complex64
,complex128
; - вещественные:
float32
,float64
.
Двукратную разницу в размерности легко объяснить: переменные типа complex
состоят из двух компонентов типа float
.
Для числовых типов доступны следующие арифметические операции:
+
— сложение,-
— вычитание,*
— умножение,/
— деление нацело,%
— остаток от деления.
Как и в языке С, для этих операций предусмотрена конструкция сокращения a = a + b
до a += b
:
Также доступны операции инкремента и декремента — сокращения a = a + 1
и a = a - 1
соответственно. В отличие, например, от С++, в Go реализованы только постфиксные версии этих операций.
Булевы значения
Для работы с логическими выражениями в Go представлен базовый тип bool
, который принимает значения true
и false
:
В отличие от JavaScript или Python, Go — строго типизированный язык. Несмотря на то что под капотом предопределённая константа false
имеет значение 0
, переменной типа bool
можно присваивать только значения такого же типа, а не любой 0
. В таком случае код выдаст ошибку компиляции из-за несоответствия типов.
Строки
В Go существует встроенный тип string
для представления текстовых данных:
Строки в Go представляют собой массив из значений типа byte
. По этой причине к элементам строки можно обращаться по индексу, а к самим строкам применима встроенная функция len
, которая возвращает её длину в байтах:
Строка хранится как массив байт, но он неизменяемый:
В данном случае длина строки в байтах равна количеству элементов, но это не всегда так. Дело в том, что Go из коробки поддерживает Unicode, а значит, строки могут содержать символы, не входящие в таблицу ASCII и не умещающиеся в один байт:
По этой же причине обращение по индексу иногда может возвращать неожидаемое значение:
Для работы с Unicode в Go предусмотрен встроенный тип rune
, способный вместить больше одного байта — любой символ таблицы Unicode. Например, с помощью него можно получить корректное количество символов из предыдущего примера:
Строковые значения в Go можно представить ещё одним способом. Если заключить строковое значение в обратные апострофы ``
, а не двойные кавычки ""
, форматирование строки будет автоматически преобразовано в управляющие символы:
Пользовательские типы
Как и большинство типизированных языков, Go позволяет программисту декларировать собственные типы. С помощью определений вы можете создавать новые типы, улучшая читаемость кода. Из-за строгости типизации вы ограничиваете определениями в том числе применимость функций и конструкций к вашим типам:
type Name string
type Fruit string
var fruit Fruit
var name Name
fruit = "Apple"
name = fruit // ошибка типизации
// cannot use fruit (variable of type Fruit) as type Name in assignment
Чтобы исправить ошибку в этом листинге, нужно явно привести fruit
к Name
.
Для пользовательских типов можно определять методы (как для классов в ООП).
Определять методы для встроенных типов в Go нельзя.
Пользовательские типы полезны для:
- разделения данных, имеющих общее представление, в зависимости от логики применения — например, чтобы по ошибке не использовать километры вместо денег, хотя оба типа определены как
int
. - определения методов.
Приведение типов
Чтобы привести один тип к другому, в Go используется такой синтаксис: type(variable)
. Проиллюстрируем на предыдущем примере:
Псевдонимы (алиасы)
В Go также есть псевдонимы (aliases) — не путайте с определениями. Псевдонимы позволяют обращаться к типу в коде по другому имени. Так, типы rune
и byte
представляют собой алиасы к int32
и uint8
:
type rune = int32
type byte = uint8
При определении алиаса после наименования типа стоит знак присваивания:
type MyString = string // MyString здесь — это псевдоним типа string
var a string
var b MyString
a = b // ошибки нет
Можно смешивать псевдонимы и изначальные типы в одном выражении.
Псевдонимы были введены в язык по настоянию Google — для решения задач крупной компании, владельца больших, смежных, пересекающихся code base
, массивов кода. Применение псевдонимов облегчает масштабный рефакторинг большого объёма уже написанного кода из разных источников. При написании «свежего» кода с чистого листа лучше обходиться без псевдонимов.
Значения по умолчанию
В отличие от языка C, идейным наследником которого является Go, любая декларация переменной и любая аллокация памяти сопровождаются инициализацией этой памяти. Если в C заявленная переменная может содержать случайное значение, оставшееся в выделенной ей памяти, то в Go переменная сначала гарантированно получает нулевое значение для своего типа.
Все типы имеют значения по умолчанию, которыми автоматически инициируется объявленная переменная, если это не было сделано явно:
- для
bool
значение по умолчанию —false
; - для числовых типов — 0;
- для ссылочных типов —
nil
или пустой указатель; - для
string
— пустая строка длиной 0.
📂 Go | Последнее изменение: 15.08.2024 14:20