Гид по технологиям

Форматирование кода Go

6 min read Go Обновлено 05 Jan 2026
Форматирование кода Go: gofmt и пакет format
Форматирование кода Go: gofmt и пакет format

Фрагмент ноутбука на переднем плане перед чашкой кофе с логотипом Go.

Форматирование кода — важный аспект читаемости, согласованности и повторного использования. Правильно отформатированный код легче читать, править и поддерживать. В языке Go есть чёткие средства для автоматического форматирования: утилита go fmt (в терминале) и пакет format (в коде). Они помогают гарантировать, что код других разработчиков будет читаться одинаково.

Пакет format и команда go fmt

Пакет format реализует стандартное форматирование исходников на Go. Он тесно интегрирован с командой go fmt, что даёт гибкость: можно форматировать файлы как извне (CLI), так и программно (в коде).

Пакет format является подпакетом в пространстве имён go. Пример импорта:

import "go/format"  

Документация по команде go fmt доступна через справку:

go help fmt

Укажите имя файла после команды fmt, чтобы отформатировать конкретный файл — go fmt поправит пробелы и отступы в соответствии со стандартом Go:

go fmt main.go  

Внутренне go fmt — это псевдоним для gofmt с флагами:

gofmt -l -w

Флаги -l и -w заставляют gofmt записать изменения в каждый переданный файл и вывести имена изменённых файлов.

Добавьте флаг -x, чтобы показать команды, выполняемые форматором (полезно для отладки):

go fmt -x main.go  

Флаг -n похож на -x, но не вносит изменений — он показывает, какие команды были бы выполнены:

go fmt -n main.go  

Флаг -n удобен, если вы хотите сначала просмотреть предпологаемые изменения, а затем применить их.

Пример небольшого файла

Вот упрощённый пример программы, которая печатает “Hello World!” пять раз. (Оставляем код в исходном виде как демонстрацию; в реальной разработке go fmt автоматически поправит формат.)

// formatting a file named main.go as shown in the example above   
  
package main  
import "fmt"  
func main() {  
  var x int=5  
  for i:=0;i

Форматирование исходников из программы

Пакет format предоставляет функцию Source, которая форматирует содержимое файла, переданное в виде байтового среза. Поток работы обычно такой: прочитать файл, передать содержимое в format.Source, затем записать результат обратно.

Пример чтения файла через ioutil.ReadFile и обработки ошибок:

fileContent, err := ioutil.ReadFile("main.go")  
  
if err != nil {  
  log.Fatalln("There was an error reading the file", err)  
}  

Передача содержимого в format.Source возвращает отформатированные байты и ошибку:

formatted, err := format.Source(fileContent)  
  
if err != nil {  
  log.Fatalln("There was a formatting error with the source function", err)  
}  

Запись результата обратно в файл через ioutil.WriteFile (указываем режим доступа):

err = ioutil.WriteFile("main.go", formatted, 0644)  
  
if err != nil {  
  log.Fatalln("There was an error writing the file", err)  
}  

Режим 0644 означает: владелец — чтение и запись; группа — чтение; остальные — без прав записи.

Вы также можете передать исходный код как литерал в байтовом срезе и отформатировать его прямо в памяти. Пример программы, которая форматирует фрагмент кода и выводит результат:

package main  
  
import (  
  "fmt"  
  "go/format"  
)  
  
func main() {  
  // simple program that calculates the area of a triangle with the math  
  // function   
  formatted, err := format.Source([]byte(`  
package main  
import(  
  "fmt"  
  "math"  
)  
func main(){  
var a float64=3  
var b float64=4  
var c float64=5  
var s float64=(a+b+c)/2  
var area float64=math.Sqrt(s*(s-a)*(s-b)*(s-c))  
fmt.Println("The area of the triangle is: ",area)  
}  
`))  
  
  if err != nil {  
    log.Fatalln("There was a formatting error with the source function", err)  
  } else {  
    fmt.Println(string(formatted))  
  }  
}  

После форматирования байтовый срез удобно преобразовать в строку через string(formatted).

Результат операции форматирования

Настройка процесса форматирования

Пакет format предоставляет структуру Config, в которой можно задать опции форматирования при создании конфигурации.

import "go/format"  
  
config := &format.Config{  
  // Tabwidth sets the number of spaces per tab.  
  Tabwidth: 8,  
  
  // UseTabs indicates whether the formatter should use tabs instead of  
  // spaces.  
  UseTabs: false,  
  
  // TabIndent is used to determine if the initial indentation should be  
  // done using tabs or spaces.  
  TabIndent: true,  
  
  // NoFinalTab specifies whether a final tab should be removed from  
  // lines before they are formatted.  
  NoFinalTab: true,  
  
  // Spaces specifies whether spaces should be used for alignment.  
  Spaces: true,  
  
  // NoTrimTrailingSpace specifies whether trailing white space should  
  // be trimmed from lines before they are formatted.  
  NoTrimTrailingSpace: false,  
}  

Поля позволяют тонко настроить поведение форматировщика в зависимости от требований проекта. После создания конфигурации можно вызвать метод Source этой структуры, чтобы отформатировать байтовый срез с учётом заданных опций.

func main() {  
  fileContent, err := ioutil.ReadFile("main.go")  
  
  // note that this is a Source method of the `config` type, not from the  
  // `format` package itself although the functionality is the same, you'll  
  // need to adhere to this if you need to configure the formatter   
  formatted, err := config.Source(fileContent)  
  
  if err != nil {  
    log.Fatalln("There was a formatting error with the config type", err)  
  }  
  
  ioutil.WriteFile("main.go", formatted, 0644)  
}  

Вызов config.Source() форматирует содержимое main.go с учётом опций и возвращает результат в виде байтового среза.

Работа со строками и дополнительными пакетами

Пакет format и команда go fmt автоматизируют форматирование кода. Для форматированного ввода-вывода и работы со строками в Go используются отдельные стандартные пакеты: fmt (форматированный ввод/вывод, похожий на printf/scanf) и strings (функции для работы со строками UTF-8).

Практические рекомендации

  • Всегда запускайте go fmt (или gofmt -w) перед коммитом или добавьте проверку в pre-commit hook. Это устраняет споры об отступах и пробелах.
  • Интегрируйте форматирование в CI: если CI находит неотформатированные файлы, CI должен возвращать ошибку и указывать команды для исправления.
  • Используйте единый стиль проекта: либо дефолтный gofmt, либо согласованная конфигурация format.Config.
  • Форматируйте код программно, если генерируете исходники автоматически.

Чек‑лист перед коммитом (роль: разработчик)

  • Запустил go fmt ./… или gofmt -w .
  • Проверил git status на отсутствующие изменения после форматирования.
  • Убедился, что CI не ругается на формат.
  • При генерации кода применил format.Source перед записью файлов.

Чек‑лист для инженера ревью (роль: ревьюер)

  • Все добавленные/изменённые файлы проходят go fmt.
  • Нет вручную изменённых отступов, которые ломают согласованный стиль.
  • Генерируемый код форматируется в CI и в локальной сборке.

Шпаргалка команд

  • go fmt ./… — отформатировать все пакеты в модуле.
  • gofmt -l . — показать список файлов с несоответствующим форматированием.
  • gofmt -w file.go — перезаписать файл отформатированным кодом.
  • go fmt -n file.go — показать, какие команды были бы выполнены.

Когда автоформатирование может не сработать

  • В сгенерированном коде могут присутствовать нестандартные маркеры или шаблоны, которые форматтер ломает; в таких случаях пометьте файл как //go:generate или используйте комментарии, чтобы отделить сгенерированный блок.
  • Если проект использует нестандартные правила (редко), автоматический форматтер может внести нежелательные изменения; лучше согласовать формат через config и автоматизацию в CI.
  • Форматтер не исправляет логические ошибки и не гарантирует безопасность — только стиль и отступы.

Альтернативные подходы

  • Ручное форматирование (не рекомендуется): большое количество времени уходит на споры о стиле.
  • Линтеры (golangci-lint и др.): совмещайте линтер и форматтер, линтеры дополняют форматирование проверками стиля и потенциальных ошибок.
  • Собственные генераторы с опцией “не трогать формат” для специфичных форматов файлов.

Ментальные модели / эвристики

  • Формат — это договор команды; чем проще правила, тем меньше «тёрок» при ревью.
  • Автоматизация = меньше человеческих ошибок + быстрее ревью.
  • В CI формат — это барьер качества: если код не проходит формат, он не проходит сборку.

Критерии приёмки

  • Все изменённые файлы проходят go fmt без изменений.
  • CI проверка форматирования включена и успешна.
  • Генерируемый код форматируется до записи файлов.

Decision flow (Mermaid)

flowchart TD
  A'Изменения в коде' --> B{Запущен ли go fmt?}
  B -- Да --> C{Файлы отформатированы?}
  B -- Нет --> D[Выполнить go fmt]
  C -- Да --> E[Продолжить коммит]
  C -- Нет --> D
  D --> F[Изменения в рабочем каталоге]
  F --> G[Перезапустить проверку CI]
  G --> C

Примеры использования в CI — мини‑методология

  1. На этапе сборки запускайте go fmt ./… и проверяйте, есть ли отличия (gofmt -l).
  2. Если есть отличия — фейлить сборку и в сообщении CI выдавать команду для разработчика (gofmt -w .).
  3. Включить pre-commit hook, который автоматически применяет gofmt и отменяет коммит, если остались несохранённые изменения.

Короткий словарь (1 строка)

  • gofmt / go fmt — стандартный форматировщик Go; format.Source — функция пакета для форматирования байтового среза; Config — структура для тонкой настройки форматтера.

Тесты и критерии приёмки

  • Unit: сгенерировать тестовый файл с неправильными отступами, применить format.Source и утверждать, что результат соответствует ожидаемому шаблону.
  • Интеграция: в CI добавить шаг, который выполняет gofmt -l и возвращает ненулевой код завершения, если есть файлы с несоответствием.

Риски и меры смягчения

  • Риск: автоматический формат может изменить поведение генерируемого кода (маловероятно, но возможно при нестандартных макросах). Митигирование: ограничьте действие форматтера на сгенерированные файлы или настройте правила генератора.
  • Риск: разные версии Go могут иметь разное поведение форматирования между релизами. Митигирование: фиксируйте версию Go в CI и в go.mod.

Итог

Автоматическое форматирование Go — маленькая, но эффективная практика, которая экономит время команды и улучшает читаемость кода. Используйте go fmt / gofmt для CLI, пакет format для программного форматирования, интегрируйте проверку в CI и применяйте простой чек‑лист перед коммитом.

Важно: форматирование не заменяет ревью логики и тестирование — оно упрощает их.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как стать рецензентом на Reedsy Discovery
Книги

Как стать рецензентом на Reedsy Discovery

Сумма первых n натуральных чисел рекурсией
Алгоритмы

Сумма первых n натуральных чисел рекурсией

Отменить подписку Minecraft Realms и сохранить мир
Minecraft

Отменить подписку Minecraft Realms и сохранить мир

Как удалить или скрыть Mail на Mac
macOS

Как удалить или скрыть Mail на Mac

Создание Lottie в After Effects — быстрый гид
Дизайн

Создание Lottie в After Effects — быстрый гид

Как изменить фото профиля в Pinterest
Социальные сети

Как изменить фото профиля в Pinterest