Документация по Go
Краткий справочник по Go с примерами. Прочитай концепцию, посмотри код, а затем потренируйся в курсе Coddy.
Начать пошаговый курс по GoНачало работы
- Что такое Go?Go (его часто называют Golang) это статически типизированный компилируемый язык, созданный в Google для быстрых и надёжных серверов и утилит. Здесь разобрано, что это за язык, где его применяют и в чём он уступает другим.
- Установка GoКак скачать и установить Go на Windows, macOS и Linux, проверить установку командой go version, разобраться с GOPATH и исправить ошибку «go: command not found».
- Hello WorldПрограмма hello world на Go построчно: package main, блок import, func main и fmt.Println, а также как её запустить и какие ошибки компиляции новички встречают первыми.
- go run и go buildЧто делают go run, go build и go install, как Go называет бинарник, как собирать под другие платформы через GOOS и GOARCH и какие проверки go fmt и go vet запускать перед коммитом.
- Модули GoКак работают модули Go: создание через go mod init, выбор пути модуля, добавление зависимостей через go get, наведение порядка через go mod tidy, зачем нужен go.sum и replace для локальной разработки.
- Пакеты и импортыКак устроены пакеты в Go: объявление package, импорт стандартных пакетов и пакетов модулей, экспортируемые и неэкспортируемые имена, пакет из нескольких файлов, internal-пакеты, псевдонимы импорта, пустые импорты и ошибка «undefined» при go run main.go.
Основы
- ПеременныеКак объявлять переменные в Go через var и короткую форму :=, что такое нулевые значения, множественное присваивание, а также ошибки затенения и неиспользуемых переменных, на которых спотыкаются новички.
- КонстантыКак работает const в Go: объявление констант, разница между типизированными и нетипизированными константами, константные выражения с произвольной точностью и почему в Go нет константных слайсов, мап и структур.
- Enum и iotaКлючевого слова enum в Go нет. Здесь показана идиоматичная замена: именованный тип плюс блок const с iota, а также как добавить String(), проверку, разбор строки, битовые флаги и поддержку JSON.
- Типы данныхВстроенные типы Go: размеры и диапазоны целых чисел, float32 и float64, bool, string, byte и rune, комплексные числа, нулевые значения и как напечатать тип значения через %T.
- Преобразование типовКак преобразовывать типы в Go: int в string и string в int через strconv, float в int, числовые преобразования через T(v), байты и руны, ловушка string(65) и обработка ошибок преобразования.
- СтрокиРабота со строками в Go: пакет strings (Split, Join, Contains, Replace, Fields, TrimSpace, ToUpper), эффективная сборка строк через strings.Builder, многострочные сырые строки, неизменяемость и почему len считает байты.
- Руны и байтыЧто означают rune и byte в Go, как строки хранят UTF-8, почему len считает байты, как range декодирует руны, преобразования между string, []byte и []rune и работа с пакетом bytes.
- fmt.Printf и SprintfКак пакет fmt в Go печатает и форматирует значения: Println, Printf, Sprintf и Errorf, полная таблица глаголов формата (%v, %+v, %d, %s, %q, %f, %T, %w и другие), ширина, точность и выравнивание.
Управление потоком
- if / elseКак работают if, else if и else в Go: без скобок вокруг условия, с обязательными фигурными скобками, if с инструкцией инициализации и его область видимости, идиома if err != nil и ранний возврат вместо глубокой вложенности.
- Цикл forВ Go одно ключевое слово для циклов, for, и оно покрывает всё: счётный цикл из трёх частей, цикл только с условием (аналог while), бесконечный цикл и range по слайсам, мапам, строкам, каналам, целым числам и функциям. А также break и continue с меткой и изменение переменных цикла в Go 1.22.
- Цикл whileВ Go нет ключевого слова while. Цикл for с одним только условием и есть while в Go, for без условия это бесконечный цикл, а do-while это бесконечный цикл с проверкой в конце.
- Циклы rangeЧто возвращает for range для слайсов, массивов, строк, мап, каналов, целых чисел и функций-итераторов, почему переменная значения это копия, что происходит при изменении слайса или мапы во время обхода и range по функциям в Go 1.23.
- Оператор switchКак работает switch в Go: ветки не проваливаются по умолчанию, в одном case можно перечислить несколько значений, switch без условия заменяет цепочки if/else, switch с инструкцией инициализации, ключевое слово fallthrough и кратко о type switch.
- Тернарный операторВ Go нет тернарного оператора (cond ? a : b). Здесь объясняется почему, показана идиоматичная замена через if/else, cmp.Or для значений по умолчанию и обобщённая функция-помощник вместе с ловушкой, которая отличает её от настоящего тернарного оператора.
Функции
- ФункцииКак объявлять и вызывать функции в Go: параметры, общий тип для нескольких параметров, возвращаемые значения, передача по значению и функции как значения, которые можно хранить и передавать.
- Несколько возвращаемых значенийФункции в Go могут возвращать несколько значений. Здесь разобраны синтаксис, соглашение (value, error), идиома comma-ok, именованные результаты, голый return и пустой идентификатор.
- Вариативные функцииВариативная функция в Go принимает любое число последних аргументов одного типа. Синтаксис ...T, передача слайса через s..., ловушка с общим массивом и то, как fmt.Println использует ...any.
- ЗамыканияАнонимные функции в Go могут захватывать переменные из окружающей области видимости. Так получаются замыкания: счётчики, генераторы, middleware и колбэки со своим состоянием.
- Оператор deferdefer откладывает вызов до момента, когда окружающая функция вернёт управление. Порядок LIFO, когда вычисляются аргументы, закрытие файлов и разблокировка мьютексов, defer в циклах и изменение именованных результатов.
- МетодыМетод это функция с получателем. Как объявлять методы, когда использовать получатель-значение, а когда указатель, наборы методов и интерфейсы, методы на типах, которые не являются структурами.
Коллекции
- МассивыМассив в Go имеет фиксированную длину, которая входит в его тип, и копируется при присваивании. Как объявлять, обходить, сравнивать и передавать массивы и почему в коде на Go чаще используют слайсы.
- СлайсыСлайсы это повседневный тип списка в Go. make, append и рост, len и cap, как срез разделяет базовый массив (и к какому багу это приводит), copy, пакет slices, двумерные слайсы, nil и пустой слайс.
- Мапы (map)Мапы в Go хранят пары ключ-значение с быстрым поиском. Как их создавать, проверять наличие ключа через comma-ok, удалять, обходить (в случайном порядке), сортировать ключи, хранить структуры и избегать паник от nil-мапы и конкурентной записи.
- МножестваВстроенного типа множества в Go нет. Стандартная идиома это мапа с пустыми структурами в качестве значений. Добавление, проверка и удаление, объединение, пересечение и разность, а также небольшой обобщённый Set.
- СортировкаСортировка слайсов в Go через slices.Sort и slices.SortFunc, сортировка структур по одному или нескольким полям через cmp.Compare, стабильная сортировка, сохраняющая порядок равных элементов, и чтение старого кода с sort.Slice.
Структуры, интерфейсы и дженерики
- СтруктурыСтруктуры объединяют именованные поля в один тип. Как их объявлять и инициализировать, нулевые значения, указатели на структуры, анонимные структуры, сравнение, теги структур и соглашение о конструкторах NewX.
- УказателиУказатель хранит адрес значения. Операторы & и *, new, указатели на структуры, почему можно безопасно вернуть указатель на локальную переменную, когда использовать указатели и паника при разыменовании nil.
- ИнтерфейсыИнтерфейсы в Go реализуются неявно: любой тип с нужными методами им удовлетворяет. Маленькие интерфейсы вроде io.Reader и fmt.Stringer, пустой интерфейс any, ловушка с nil в интерфейсе и принцип «принимай интерфейсы, возвращай структуры».
- Встраивание структурВстраивание помещает один тип внутрь другого без имени поля, и его поля и методы продвигаются во внешний тип. Как работает продвижение, встраивание интерфейсов, конфликты имён и почему встраивание не является наследованием.
- Утверждения типаУтверждение типа достаёт конкретное значение из интерфейса. x.(T), форма comma-ok, которая никогда не паникует, утверждение к другому интерфейсу, type switch и errors.As для обёрнутых ошибок.
- ДженерикиДженерики (Go 1.18+) позволяют одной функции или типу работать со многими типами, сохраняя типобезопасность. Параметры типа, ограничения any, comparable и cmp.Ordered, свои ограничения с ~, обобщённые типы и когда дженерики не нужны.
Ошибки
- Обработка ошибокВ Go ошибки это обычные значения, которые возвращают функции. Интерфейс error, if err != nil, errors.New и fmt.Errorf, возврат ошибок с контекстом, их проверка через errors.Is и errors.As и правило обрабатывать каждую ошибку один раз.
- Собственные ошибкиКак объявлять ошибки-маркеры и собственные типы ошибок, оборачивать ошибки через %w, проверять их через errors.Is и errors.As, объединять несколько через errors.Join и писать методы Unwrap и Is, когда они нужны.
- panic и recoverПаника прерывает обычное выполнение и раскручивает стек, выполняя отложенные вызовы. Что вызывает паники, как recover в отложенной функции их останавливает, какие сообщения среды выполнения вы увидите и когда паника это правильное решение.
Конкурентность
- ГорутиныКак запускать функции конкурентно с помощью ключевого слова go, дожидаться их завершения, получать результаты и избегать гонок данных, утечек и падений, которые с горутинами получаются так легко.
- КаналыКак каналы в Go передают значения между горутинами: небуферизованные и буферизованные каналы, закрытие и обход через range, типы с направлением, ошибка deadlock и конвейер, собранный из каналов.
- Оператор selectКак select ждёт сразу несколько операций с каналами: выбор среди готовых веток, неблокирующие отправка и получение через default, таймауты через time.After и остановка циклов через канал quit или context.
- WaitGroupКак sync.WaitGroup ждёт завершения группы горутин: правила Add, Done и Wait, почему его передают по указателю, сбор результатов и ошибок и пул воркеров на его основе.
- МьютексКак защищать общее состояние между горутинами через sync.Mutex и sync.RWMutex, когда достаточно sync/atomic, как sync.Once выполняет инициализацию ровно один раз и какие ошибки блокировок приводят к deadlock.
- Пакет contextКак context.Context передаёт через программу на Go отмену, дедлайны и значения уровня запроса: Background, WithCancel, WithTimeout, WithValue, ctx.Done в select и context в HTTP-серверах и клиентах.
Стандартная библиотека
- Пакет timeКак работать с датами и временем в Go: time.Now и time.Sleep, арифметика Duration, эталонная раскладка 2006-01-02 15:04:05 для Format и Parse, часовые пояса, Unix-время, таймеры и тикеры.
- JSONКак кодировать и декодировать JSON в Go через encoding/json: Marshal и Unmarshal, теги структур вроде omitempty и omitzero, красивый вывод, декодирование в map[string]any, отказ от неизвестных полей и потоковая обработка через Decoder.
- Чтение и запись файловКак читать и записывать файлы в Go: os.ReadFile и os.WriteFile, построчное чтение через bufio.Scanner, дозапись через os.OpenFile, проверка существования файла и работа с папками.
- HTTP-серверКак построить веб-сервер на стандартном пакете net/http: обработчики, маршрутизация ServeMux с методами и шаблонами в пути (Go 1.22), JSON-ответы, коды статуса, middleware, таймауты и корректное завершение.
- HTTP-клиентКак делать HTTP-запросы в Go через net/http: http.Get, чтение и закрытие тела, проверка кодов статуса, таймауты http.Client, запросы с контекстом и заголовками, параметры строки запроса и POST с JSON.
- Аргументы командной строкиКак программа на Go читает командную строку: os.Args, пакет flag для типизированных опций, подкоманды через FlagSet, переменные окружения через os.Getenv и os.LookupEnv и коды выхода через os.Exit.
- Регулярные выраженияКак использовать регулярные выражения в Go через пакет regexp: MustCompile, MatchString, FindString и FindAllString, группы захвата и именованные группы, ReplaceAllString и ограничения синтаксиса RE2, например отсутствие lookbehind.
- ЛогированиеКак логировать в Go: классический пакет log с его флагами и log.Fatal и log/slog (Go 1.21) для структурированных логов с уровнями, атрибутами ключ-значение, текстовыми и JSON-обработчиками и логгерами, которые несут контекст через With.
Тестирование и структура проекта
- ТестированиеКак тестировать код на Go стандартным пакетом testing и командой go test: файлы _test.go, функции TestXxx, t.Errorf и t.Fatalf, табличные тесты с t.Run, помощники и временные папки, покрытие, бенчмарки через b.Loop и тесты-примеры.
- Структура проектаКак организовать проект на Go: начать с плоской структуры, делить на пакеты, когда есть причина, использовать cmd/ для нескольких бинарников и internal/ для кода, который никто больше не должен импортировать, хорошо называть пакеты и держать тесты рядом с кодом.