Ответ
Ответ можно разделить на две части: структуры, предоставляемые языком и стандартной библиотекой, и классические структуры, которые реализуются вручную.
Встроенные и стандартные структуры данных
-
Массивы (Arrays)
- Последовательность элементов одного типа с фиксированной длиной. Размер массива является частью его типа. Являются value-типами (при присваивании или передаче в функцию происходит полное копирование).
var arr [3]int = [3]int{1, 2, 3}
- Последовательность элементов одного типа с фиксированной длиной. Размер массива является частью его типа. Являются value-типами (при присваивании или передаче в функцию происходит полное копирование).
-
Срезы (Slices)
- Динамический, гибкий и более удобный аналог массива. Срез — это легковесная структура-дескриптор, которая ссылается на непрерывный сегмент базового массива (backing array). Содержит указатель на начало сегмента, его длину (
len
) и ёмкость (cap
). Является reference-типом.slice := []int{1, 2, 3} slice = append(slice, 4) // Длина и ёмкость могут меняться
- Динамический, гибкий и более удобный аналог массива. Срез — это легковесная структура-дескриптор, которая ссылается на непрерывный сегмент базового массива (backing array). Содержит указатель на начало сегмента, его длину (
-
Карты (Maps)
- Хеш-таблица, хранящая пары "ключ-значение". Является reference-типом. Порядок итерации по элементам карты не гарантирован.
m := make(map[string]int) m["age"] = 30
- Хеш-таблица, хранящая пары "ключ-значение". Является reference-типом. Порядок итерации по элементам карты не гарантирован.
-
Строки (Strings)
- Неизменяемая (immutable) последовательность байт. Внутренне похожа на срез байт
[]byte
, но её содержимое нельзя изменить после создания.
- Неизменяемая (immutable) последовательность байт. Внутренне похожа на срез байт
-
Структуры (Structs)
- Композитный тип данных, который объединяет поля разных типов в единое целое.
type Person struct { Name string Age int }
- Композитный тип данных, который объединяет поля разных типов в единое целое.
-
Пакет
container
container/list
: Реализация двусвязного списка.container/heap
: Интерфейс для реализации кучи (пирамиды). Может использоваться для создания min-heap или max-heap поверх среза.
Реализация классических структур данных
Поскольку стандартная библиотека Go минималистична, некоторые структуры данных реализуются вручную.
-
Стек (Stack) и Очередь (Queue)
- Легко реализуются на основе среза. Стек использует LIFO (Last-In, First-Out), а очередь — FIFO (First-In, First-Out).
// Стек stack := []int{} stack = append(stack, 10) // Push val := stack[len(stack)-1] // Peek stack = stack[:len(stack)-1] // Pop
- Легко реализуются на основе среза. Стек использует LIFO (Last-In, First-Out), а очередь — FIFO (First-In, First-Out).
-
Множество (Set)
- Идиоматичный способ реализации множества в Go — это использование
map
с пустыми структурами в качестве значений, так какstruct{}
не занимает памяти.set := make(map[string]struct{}) set["apple"] = struct{}{} set["orange"] = struct{}{}
if _, exists := set["apple"]; exists { // Элемент существует }
- Идиоматичный способ реализации множества в Go — это использование
-
Деревья (Trees) и Графы (Graphs)
- Реализуются с помощью структур и указателей. Например, бинарное дерево:
type TreeNode struct { Value int Left *TreeNode Right *TreeNode }
- Графы часто представляют списком смежности (
map[T][]T
) или матрицей смежности ([][]bool
).
- Реализуются с помощью структур и указателей. Например, бинарное дерево: