Code Review in Go: What to Check and How to Give Feedback

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Code review в Go: что проверять и как давать обратную связь



Code review (ревью кода) — это не просто формальность, а один из самых эффективных инструментов для повышения качества кода, обмена знаниями в команде и предотвращения багов. В сообществе Go (Golang) code review имеет особое значение, так как язык поощряет простоту, читаемость и идиоматичность. В этой статье мы разберем, на что обращать внимание при ревью Go-кода и как давать обратную связь, чтобы она была полезной, а не обидной.



1. Общие принципы code review в Go

Прежде чем переходить к техническим деталям, важно помнить о культуре ревью. Ваша цель — улучшить код и помочь коллеге, а не доказать свою правоту. Вот несколько золотых правил:

  • Будьте конструктивны. Вместо «это плохо» напишите «здесь может быть утечка горутины, давай добавим контекст».
  • Спрашивайте, а не утверждайте. «Почему ты выбрал sync.Mutex, а не канал?» — хороший вопрос. «Ты дурак, надо было канал» — плохой.
  • Не задерживайте ревью. Стремитесь дать ответ в течение 24 часов (или по договоренности в команде).
  • Фокусируйтесь на логике и архитектуре. Стилистические правки (пробелы, отступы) лучше доверить gofmt.


2. Что проверять в первую очередь: чек-лист для Go

Вот структурированный список того, на что стоит обращать внимание при ревью Go-кода. Разделим его на логические блоки.



2.1. Обработка ошибок

В Go нет исключений, ошибки — это значения. Это одна из ключевых идиом языка.

  • Проверяйте все возвращаемые ошибки. Игнорирование ошибки с помощью _ допустимо только в очень редких случаях (например, при записи в io.Discard).
  • Не используйте panic для обычных ошибок. panic — это для невосстановимых состояний (например, ошибка инициализации сервера).
  • Оборачивайте ошибки. Используйте fmt.Errorf("что-то пошло не так: %w", err) для добавления контекста. Это позволяет использовать errors.Is() и errors.As().
// Плохо: потеря контекстаif err != nil {    return err}

// Хорошо: оборачиваем ошибкуif err != nil { return fmt.Errorf("не удалось открыть файл %s: %w", filename, err)}


2.2. Горутины и конкурентность

Go славится своей легковесной конкурентностью, но она же является источником многих багов.

  • Утечки горутин. Убедитесь, что каждая запущенная горутина когда-нибудь завершится. Используйте контекст (context.Context) для отмены.
  • Правильное использование каналов. Кто создает канал, тот и закрывает его. Закрытие канала — это ответственность отправителя.
  • Гонка данных (data race). Избегайте одновременной записи в одну переменную без синхронизации. Используйте мьютексы (sync.Mutex) или атомики (sync/atomic).
// Пример с контекстом для отмены горутиныfunc process(ctx context.Context, dataCh chan int) {    for {        select {        case <-ctx.Done():            log.Println("Завершаем работу")            return        case val, ok := <-dataCh:            if !ok {                return // канал закрыт            }            fmt.Println(val)        }    }}


2.3. Идиомы и стиль Go

Go — это язык, где читаемость кода ценится превыше всего.

  • Имена переменных. Короткие имена для коротких областей видимости. i для цикла, r для reader. Для глобальных переменных — более длинные имена.
  • Избегайте «магических чисел». Используйте константы.

Blogs

Book Recommendations