Как отлаживать 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).