📦 Типы данных в Go: подробный гид для начинающих
Тип данных — это ключевое понятие в любом языке программирования. В Go типы данных особенно важны, потому что язык статически типизированный: ты всегда должен указывать или явно понимать, какой именно тип данных хранит каждая переменная.
🧩 Почему типы данных важны?
Тип данных говорит компилятору Go:
- Какой объём памяти нужен для хранения значения.
- Какие операции можно выполнять с данными.
- Какие проверки и преобразования допустимы.
Это делает программы более надёжными, понятными и безопасными.
📌 Основные типы данных в Go
1️⃣ Числовые типы (int
, float
)
В Go есть целые числа (int
) и числа с плавающей точкой (float32
, float64
):
var age int = 30 var price float64 = 19.99
Целочисленные типы предназначены для хранения чисел без дробной части. В Go есть несколько конкретных целочисленных типов, которые отличаются диапазоном значений и размером в памяти:
+-----------+--------------------+----------------------------------------------+ | Тип | Размер (в памяти) | Диапазон значений | +-----------+--------------------+----------------------------------------------+ | int8 | 8 бит (1 байт) | от -128 до 127 | | int16 | 16 бит (2 байта) | от -32,768 до 32,767 | | int32 | 32 бита (4 байта) | от -2,147,483,648 до 2,147,483,647 | | int64 | 64 бита (8 байт) | от -9,223,372,036,854,775,808 | | | | до 9,223,372,036,854,775,807 | | uint8 | 8 бит (1 байт) | от 0 до 255 | | uint16 | 16 бит (2 байта) | от 0 до 65,535 | | uint32 | 32 бита (4 байта) | от 0 до 4,294,967,295 | | uint64 | 64 бита (8 байт) | от 0 до 18,446,744,073,709,551,615 | | int | 32 или 64 бита | зависит от платформы (чаще всего 64-бит) | | uint | 32 или 64 бита | зависит от платформы (чаще всего 64-бит) | +-----------+--------------------+----------------------------------------------+
Пример:
package main import "fmt" func main() { var age int = 25 var temperature int8 = -10 var distance uint16 = 1500 fmt.Println("Возраст:", age) fmt.Println("Температура:", temperature) fmt.Println("Расстояние:", distance) }
int
— наиболее часто используемый тип, он автоматически выбирает размер (32 или 64 бита) в зависимости от твоей ОС и платформы.
Когда использовать?
Используй целочисленные типы, когда данные точно не имеют дробной части:
📌 Числа с плавающей точкой (float)
Числа с плавающей точкой используются, когда нужны точность и дробная часть. В Go есть два типа float:
+-----------+--------------------+-----------------------------------------------+ | Тип | Размер (в памяти) | Точность | +-----------+--------------------+-----------------------------------------------+ | float32 | 32 бита (4 байта) | ~6-7 десятичных цифр точности | | float64 | 64 бита (8 байт) | ~15-17 десятичных цифр точности | +-----------+--------------------+-----------------------------------------------+
По умолчанию Go использует тип float64
.
Пример:
package main import "fmt" func main() { var price float64 = 19.99 var pi float32 = 3.14159 fmt.Println("Цена:", price) fmt.Println("Число Пи:", pi) }
Когда использовать?
Используй float-числа, когда нужно представлять вещественные значения, например:
🐾 Кошачий пример про числа в Go:
Представь, что целые числа (int
) — это количество котов 🐱:
Нельзя иметь полтора кота, только 1, 2, 3 и так далее.
А числа с плавающей точкой (float
) — это количество корма 🥘:
Его можно точно измерить, например, 0.5 кг или 1.25 кг.
Go внимательно следит за тем, чтобы ты не перепутал эти два типа.
2️⃣ Строки (string
)
Строки в Go неизменяемы и хранятся в UTF-8:
var name string = "Барсик" fmt.Println("Котика зовут:", name)
Строки в Go представляют собой последовательность символов, закодированных в формате UTF-8. Это означает, что строки могут включать любые символы — от простого текста на латинице до эмодзи и символов на других языках. Важно отметить, что строки в Go неизменяемые: после создания строки нельзя изменить отдельный символ. Любое изменение строки приводит к созданию новой строки.
Используй строки для хранения текста, имён, сообщений, JSON-ответов, URL и любой другой информации, представленной в виде текста.
3️⃣ Логический тип (bool
)
Тип, который может принимать значение только true
или false
:
var isCatCute bool = true
Тип bool
— это самый простой тип данных, который может хранить только два возможных значения: true
(истина) или false
(ложь). Этот тип часто используется в условиях, циклах и проверках. Например, можно проверять авторизацию пользователя (isAuthorized
), статус выполнения задачи (isCompleted
), или просто контролировать включение/отключение какой-либо функции.
4️⃣ Массивы (array
)
Массивы в Go — это фиксированный набор элементов одного типа:
var nums [3]int = [3]int{1, 2, 3}
Массивы в Go — это фиксированный по размеру набор данных одного типа. Их размер строго определяется заранее и не может быть изменён после создания. Если нужно хранить набор фиксированной длины (например, дни недели или месяцы года), массив отлично подойдёт. Однако, из-за ограничений по изменению размера, для большинства задач используют не массивы, а срезы (slices
).
5️⃣ Срезы (slice
)
Срезы — более гибкий аналог массивов, которые можно увеличивать и уменьшать:
var nums []int = []int{1, 2, 3} nums = append(nums, 4) // добавили элемент
Срез (slice) в Go — это удобная и гибкая структура данных, которая позволяет хранить набор элементов одного типа и динамически изменять их количество. В отличие от массивов, срезы не имеют фиксированной длины и могут расти и уменьшаться по мере необходимости.
Срезы были созданы специально для упрощения работы с наборами данных, когда заранее неизвестно их точное количество. Ты можешь добавлять, удалять и изменять элементы среза в процессе работы приложения.
🔍 Чем срез отличается от массива?
Главное отличие: массивы в Go имеют фиксированный размер, который задаётся в момент создания и не может быть изменён. Срезы же изначально гибкие и могут динамически увеличиваться и уменьшаться в размере.
🚧 Как срезы устроены внутри?
Срез в Go хранит три важных вещи:
- Указатель на первый элемент в массиве, который хранит реальные данные.
- Длина (length) — текущее количество элементов.
- Ёмкость (capacity) — максимально возможное количество элементов, которые могут быть сохранены без необходимости выделения новой памяти.
Когда ты добавляешь элементы в срез и текущая ёмкость исчерпывается, Go автоматически создаёт новый, больший по размеру массив, копирует туда данные и продолжает работу уже с новым массивом.
📌 Когда использовать массив, а когда срез?
- Используй массивы, если у тебя есть точное количество элементов, которое никогда не изменится. Например, названия дней недели (7 элементов), месяцы года (12 элементов), координаты (X, Y, Z — 3 элемента).
- Используй срезы во всех остальных случаях: когда нужно хранить список пользователей, задачи в приложении, список товаров в корзине и любые другие динамические наборы данных.
🐾 Кошачий пример про срезы и массивы:
Представь, что массив — это коробка из-под обуви для котов. Она жёсткая и её размер нельзя поменять. В неё поместится ровно столько котов, сколько запланировано заранее.
А срез — это как большой мягкий диван для котов: сколько бы их ни пришло, они всегда смогут разместиться удобно, диван может быть больше и больше, по мере прибытия новых котов.
6️⃣ Карты (map
)
var user = map[string]int{ "Alice": 25, "Bob": 30, } fmt.Println(user["Alice"]) // 25
7️⃣ Структуры (struct
)
Пользовательский тип, объединяющий разные данные:
type Cat struct { Name string Age int } var barsik Cat = Cat{Name: "Барсик", Age: 3}
Структуры в Go позволяют объединять данные разных типов в один логически связанный объект. Это своего рода шаблон или схема для описания сложных типов данных. Например, структуру можно использовать для описания пользователя (имя, возраст, email) или для описания конфигурации приложения (адрес сервера, порт, настройки безопасности). Структуры не поддерживают наследование (как классы в других языках), но могут содержать методы и реализовывать интерфейсы, что делает их очень гибким инструментом для организации кода и данных.
8️⃣ Указатели (pointer
)
Хранят адрес другого значения в памяти:
var a int = 10 var ptr *int = &a fmt.Println(*ptr) // 10
Указатели — это особый тип данных, хранящий не значение, а адрес ячейки памяти, где это значение хранится. Указатели позволяют эффективно передавать данные между функциями без копирования значений (особенно больших структур), а также изменять значение переменных напрямую в памяти. Хотя указатели требуют внимательности и осторожности (чтобы избежать ошибок), они обеспечивают очень мощный механизм работы с памятью и оптимизации приложений.
⚙️ Особые типы в Go
🌀 Интерфейсы (interface
)
Интерфейс — тип, который описывает поведение (методы):
type Animal interface { Speak() string }
🔄 Приведение и преобразование типов
Go требует явного приведения типов:
var x int = 10 var y float64 = float64(x) // явное приведение int → float64
⚠️ Zero values (нулевые значения)
Если переменная объявлена, но не инициализирована, Go присваивает ей нулевое значение:
🐾 Кошачий пример про типы данных
Представь, что типы данных — это миски с разным кормом.
- Если коту дать миску (
int
), то в неё нельзя положить молоко (string
). - Каждой миске соответствует конкретный тип еды (данных).
- Go всегда проверяет, чтобы котик получил правильную еду (данные).
Итог
Теперь у тебя есть полная картина о типах данных в Go! Каждый тип данных имеет свои особенности, и понимание их поможет тебе писать более эффективный и правильный код. 🚀🐹