Как отлаживать Go-приложения локально?

Ответ

Существует два основных подхода к отладке Go-приложений: использование полноценного отладчика и простой вывод в консоль (логирование).

1. Использование отладчика Delve (dlv)

Delve — это стандартный и самый мощный отладчик для Go. Он позволяет останавливать выполнение программы, исследовать состояние переменных, пошагово выполнять код и многое другое.

Установка:

go install github.com/go-delve/delve/cmd/dlv@latest

Базовый рабочий процесс в терминале:

  1. Запуск отладки: Скомпилировать и запустить приложение под управлением Delve.

    dlv debug ./cmd/my-app/main.go
  2. Установка точек останова (breakpoints):

    (dlv) break main.main  // на входе в функцию main
    (dlv) break main.go:25 // на строке 25 в файле main.go
  3. Запуск и навигация:

    • continue (или c): продолжить выполнение до следующей точки останова.
    • next (или n): перейти на следующую строку (не заходя внутрь функций).
    • step (или s): зайти внутрь вызываемой функции.
    • stepout: выйти из текущей функции на уровень выше.
  4. Просмотр состояния:

    • print myVar (или p myVar): напечатать значение переменной.
    • locals: показать все локальные переменные.
    • args: показать аргументы функции.

Интеграция с IDE: Все популярные IDE (VS Code, GoLand) имеют встроенную интеграцию с Delve. Они предоставляют удобный графический интерфейс для управления отладкой, что значительно упрощает процесс.

2. Простой способ: Логирование

Для быстрой проверки значений или логики выполнения часто достаточно простого вывода в консоль. Это самый быстрый, хотя и менее гибкий способ.

import (
    "fmt"
    "log"
)

func someFunction(a, b int) {
    log.Printf("Функция someFunction вызвана с параметрами a=%d, b=%d", a, b)

    result := a + b

    // Используем fmt.Printf для форматированного вывода со всеми деталями
    fmt.Printf("Промежуточный результат: %+vn", result)

    // ... остальная логика
}

Этот метод полезен для отладки в средах, где сложно подключить полноценный отладчик (например, в некоторых Docker-контейнерах или CI/CD).

Ответ 18+ 🔞

А, ну так, слушай, про отладку в Go. Тут, блядь, как в жизни — либо ты всё по-взрослому, с инструментами, либо как последний распиздяй, через fmt.Println тыкаешься, пока не заработает.

Первый подход — это Delve, он же dlv. Это, ёпта, как швейцарский нож для твоего кода. Не просто посмотреть, а прямо внутри залезть, всё потрогать, выполнить по шагам. Мощная штука, хотя сначала кажется, что хуй разберёшься.

Ставится просто:

go install github.com/go-delve/delve/cmd/dlv@latest

А дальше начинается магия. Запускаешь свою прогу под его присмотром:

dlv debug ./cmd/my-app/main.go

И вот ты уже в его консоли. Тут, блядь, главное не охуеть от возможностей.

  • Хочешь остановиться в конкретном месте — брейкпоинт ставь:
    (dlv) break main.go:42 // Остановись, сука, на 42-й строке, я хочу посмотреть!
  • Дальше команды, как в танке: continue — поехали до следующей остановки, next — шаг вперёд, но мимо функций, step — а вот это уже заходим внутрь, смотрим, что там творится.
  • А самое сокровенное — смотреть, что в переменных творится. print myVar — и ты видишь её значение. locals — и тебе все локальные переменные вываливают, как будто карты на стол. Удобно, блядь, до охуения.

И если ты не консольный маньяк, то все нормальные IDE (VS Code, GoLand) эту хуйню умеют в красивый интерфейс заворачивать. Тыкаешь мышкой слева от строки — точка останова, жмёшь F5 — и понеслась. Красота.

А второй подход — это логгирование, оно же «дедовский метод». Когда всё по-простому, по-быстрому, без наворотов. Иногда это единственный способ, если ты, например, в каком-нибудь долбаном контейнере сидишь, где отладчик не прикрутить.

import (
    "fmt"
    "log"
)

func someShittyFunction(a, b int) {
    // log.Printf — для серьёзных пацанов, с таймстемпом
    log.Printf("Зашли в функцию, a=%d, b=%d. Погнали.", a, b)

    result := a + b
    // А fmt.Printf — когда надо быстро и прямо в stdout плюнуть
    fmt.Printf("Смотри-ка, промежуточный результат: %+vn", result)

    // ... дальше твой гениальный код, который не работает
}

Это как молотком по пальцу: примитивно, больно, но часто работает. Быстро вставил, запустил, увидел, где пиздец, исправил. Но, конечно, если проблема сложная, то ты этим Printf-ом весь экран засираешь, а толку — ноль, волнение ебать. Тут уже без делва не обойтись.

Короче, выбор за тобой. Для серьёзных разборок — dlv, царь и бог. Для быстрой проверки «а что, блядь, тут вообще лежит?» — старый добрый вывод в консоль. Главное — чтобы работало, а то сидишь, ебёшься, а оно не пашет, терпения ноль ебать.