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

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

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

Code review — это не просто формальность, а важнейший этап разработки. Особенно в Go, где простота и читаемость кода заложены в философию языка. Для начинающих разработчиков это может казаться пугающим: как критиковать чужой код, если сам ещё не уверен? На самом деле, code review — это лучший способ учиться. В этой статье мы разберём, на что обращать внимание при ревью Go-кода и как давать обратную связь, чтобы она была полезной, а не обидной.

1. Основные принципы: что искать в первую очередь

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

  • Логические ошибки: корректно ли обрабатываются граничные случаи? Например, что будет, если слайс пуст?
  • Потенциальные паники: не забыли ли вы про nil? Проверьте, что не вызываете методы на нулевом указателе.
  • Неиспользуемый код: в Go это приводит к ошибке компиляции, но иногда остаются мёртвые переменные или импорты.

Пример типичной ошибки новичка:

func getFirstElement(s []int) int {
    return s[0] // Паника, если слайс пуст!
}

Что нужно предложить в ревью: добавить проверку длины слайса и вернуть ошибку.

func getFirstElement(s []int) (int, error) {
    if len(s) == 0 {
        return 0, fmt.Errorf("slice is empty")
    }
    return s[0], nil
}

2. Идиомы Go: как писать «по-гошному»

Go — не Java и не Python. У него свой стиль, который нужно уважать. На ревью обращайте внимание на следующие моменты:

  • Именование: в Go приняты короткие имена (например, r для reader, w для writer). Не нужно называть переменную myReader — просто r.
  • Обработка ошибок: не игнорируйте ошибки! Если функция возвращает error, её нужно проверить. Исключение — fmt.Println и подобные, но и их лучше логировать.
  • Интерфейсы: они должны быть маленькими. Один метод — хорошо, два — уже много. Не создавайте интерфейсы «на вырост».

Пример «не-гошного» кода:

func ProcessData(data []string) (bool, error) {
    var result bool
    for _, item := range data {
        if item == "error" {
            result = false
            return result, errors.New("found error")
        }
    }
    result = true
    return result, nil
}

Здесь result не нужен — можно сразу возвращать true или false. Также стоит использовать fmt.Errorf для форматирования.

func ProcessData(data []string) (bool, error) {
    for _, item := range data {
        if item == "error" {
            return false, fmt.Errorf("found error in item: %s", item)
        }
    }
    return true, nil
}

3. Производительность и память: на что обратить внимание

Хотя Go достаточно быстр, плохой код может всё испортить. На ревью проверяйте:

  • Избегайте лишних аллокаций: если вы знаете размер слайса, используйте make с указанием capacity.
  • Копирование структур: большие структуры лучше передавать по указателю, чтобы не копировать их каждый раз.
  • Горутины: проверьте, не забыли ли вы закрыть канал или дождаться завершения горутины (используйте sync.WaitGroup).

Пример плохой работы со слайсом:

func appendItems(items []int) []int {
    var result []int
    for _, v := range items {
        result = append(result, v*2)
    }
    return result
}

Лучше так:

func appendItems(items []int) []int {
    result := make([]int, 0, len(items))
    for _, v := range items {
        result = append(result, v*2)
    }
    return result
}

Это снижает количество переаллокаций памяти.

4. Как давать обратную связь: мягко и конструктивно

Даже если вы нашли 100 ошибок, не вываливайте их все сразу. Используйте правило «сэндвича»: начните с позитива, затем укажите на проблемы, закончите поддержкой. Вот несколько конкретных советов:

  • Используйте вопросительную форму: вместо «Ты написал неправильно» скажите «А что, если здесь передать nil? Нужна ли проверка?»
  • Предлагайте альтернативы: не просто указывайте на ошибку, а покажите, как её исправить. Пример: «Вместо цикла можно использовать strings.Join, это упростит код».
  • Не спорьте о вкусовщине: если код рабочий и читаемый, не настаивайте на переименовании переменной с i на index. Это не важно.

Пример хорошего комментария:

«Отличная реализация! Я заметил, что здесь может быть паника, если map не инициализирован. Предлагаю добавить проверку if m == nil в начале функции. Что думаешь?»

5. Чек-лист для начинающего ревьюера

Чтобы не забыть важное, держите под рукой этот список:

  • Код компилируется? (go build)
  • Проходят ли тесты? (go test ./...)
  • Нет ли неиспользуемых переменных или импортов?
  • Обрабатываются ли ошибки?
  • Нет ли паник из-за nil?
  • Соблюдены ли идиомы Go (именование, интерфейсы)?
  • Нет ли утечки горутин?
  • <

Блоги

Рекомендаций по книгам