Go — компилируемый, статически типизированный язык от Google. Отличается простотой синтаксиса, встроенной конкурентностью (goroutines, каналы), быстрой компиляцией в один статический бинарник, автоматической сборкой мусора и богатым стандартным пакетом. В отличие от Java/C#, нет наследования классов и исключений; вместо этого — композиция, интерфейсы по неявной реализации и ошибка как значение.
Плюсы: простота, скорость компиляции, кроссплатформенные статические бинарники, встроенная конкурентность, стабильный ABI на уровне пакета, богатый stdlib, инструменты из коробки (fmt, vet, test). Минусы: ограниченная дженерик-система (появились в Go 1.18, но без метапрограммирования), нет исключений, ограниченные возможности наследования, простая система управления пакетами (модули) без сложных workspaces до недавнего времени.
Статическая, сильная типизация. Есть базовые типы (числа, bool, string), составные (array, slice, map, struct, function, channel, pointer, interface). Пользовательские типы объявляются через type. Есть дженерики (параметризованные типы/функции), типовые ограничения (constraints) и интерфейсы с неявной реализацией.
Значения по умолчанию для переменных при инициализации: 0 для чисел, false для bool, “” для string, nil для ссылочных типов (slice, map, pointer, channel, function, interface). Zero value всегда корректен к использованию, но некоторые операции требуют явной инициализации (например, make для map/channel/slice).
Указатель хранит адрес значения (*T). Оператор & берёт адрес, * разыменовывает. Нельзя выполнять арифметику указателей. Метод с receiver-ом *T может изменять состояние, а с T — работает с копией.
var — объявление с возможной инициализацией, доступно в любом блоке и на уровне пакета. := — короткое объявление и инициализация только внутри функции. const — постоянные на этапе компиляции для чисел, строк, bool; могут быть типизированные или нетипизированные.
Числовые (int, uint, размеры, float32/64, complex64/128), логический bool, строка string, указатели, массивы, срезы, карты (map), структуры (struct), функции, интерфейсы, каналы, дженерик-параметры.
byte — псевдоним для uint8, хранит один байт. rune — псевдоним для int32, хранит один Unicode кодпоинт. Строка — это неизменяемая последовательность байтов UTF-8, а не rune-ов.
Array — фиксированная длина, часть типа ([3]int). Slice — дескриптор (указатель, длина, ёмкость), указывает на подмассив и динамически растёт через append. Срез — ссылочный тип; копирование среза копирует дескриптор, а не данные.
Добавляет элементы в срез. Если хватает capacity — записывает в тот же underlying array; если нет — аллоцирует новый массив (обычно рост ≈×2), копирует данные и возвращает новый срез. Всегда использовать возвращаемое значение: s = append(s, x).
map[K]V — хеш-таблица. Внутри — массив бакетов, в бакете хранятся несколько пар ключ-значение и метки хеша. При росте — рехеширование (инкрементальное). Нулевое значение nil непригодно для записи: требуется make(map[K]V) или литерал.
Через «comma ok» идиому: v, ok := m[k]. Если ok == true, ключ существует; иначе v — zero value типа V.
nil применим только к ссылочным типам и означает «нет значения/адреса». Пустая строка “”, пустой массив [0]T{}, пустой срез []T{} — это валидные значения. У пустого среза len=0, а cap может быть 0; nil-срез тоже имеет len=0, но nil указатель внутри.
Откладывает выполнение функции до выхода из текущей функции (включая панический выход). Аргументы вычисляются немедленно, вызов — позже. Полезно для закрытия ресурсов.
panic инициирует «панический» выход по стеку с выполнением всех defer. recover перехватывает панику, если вызван внутри отложенной функции. defer — просто механизм отложенного вызова, не связанный с ошибками напрямую.
LIFO — последний объявленный defer выполнится первым.
Единица компиляции и импортов. Директория = пакет (кроме main, формирующего исполняемый файл). Экспортируемые имена начинаются с заглавной буквы. Импорт через import “path”.
Имя модуля + путь пакета. Управление зависимостями — через Go Modules (go mod init, go get). Можно задавать алиасы: import foo “example.com/x/y”. Пустой импорт (_ “pkg”) — для побочных эффектов (вызова init).
Функция пакета, выполняется до main() и после инициализации переменных. Используется для регистрации, проверки окружения, установки глобальных переменных. Может быть несколько init в одном пакете/файле.
Счётчик констант в блоке const, начинается с 0 и увеличивается на 1 в каждой строке. Удобен для перечислений и битовых масок.
Ошибка — это значение типа error. Возвращается как последний результат: v, err := f(). Проверяется явно: if err != nil { … }. Для дополнительного контекста используют обёртки (fmt.Errorf(“…: %w”, err)) и errors.Is/As.
error — управляемая, ожидаемая ошибка бизнес-логики или окружения; обрабатывается и возвращается вызывающему коду. panic — критическая ситуация (инвариант нарушен), обычно не для обычного потока выполнения; приводит к падению, если не перехвачена recover.
Форматированный вывод в стиле printf: %s — строка, %d — десятичное целое, %v — «как есть», %+v — с полями, %#v — Go-литерал, %T — тип, %f — float, %t — bool. Управление шириной/точностью через флаги.
new(T) выделяет память под T и возвращает *T, заполняя zero value. make инициализирует внутренние структуры ссылочных типов (slice, map, channel) и возвращает сам значение этого типа, готовое к использованию.