Статьи

Рефакторинг с Go Fmt

Я недавно начинал. Я собрал несколько пакетов и библиотек .

Для этого поста давайте рассмотрим инструмент ‘gofmt’ или ‘go fmt’.

Отправляйте с базовым набором инструментов, общим для большинства языков и сред разработки. Как и большинство других вещей, инструменты просты по конструкции, но мощны по функциям.

  • go build — скомпилировать код
  • go install — установить (пересобрать сборку) пакет
  • go get — скачать и установить пакеты, включая зависимости
  • go test — запустить тестовые наборы и тесты
  • Go Doc — генерировать и просматривать документацию
  • go fmt — отформатируйте и реорганизуйте ваш код
  • Go Run — создавать и запускать приложения

Прежде всего, обратите внимание, что ‘go fmt’ — это просто псевдоним для ‘gofmt -l -w’. Следуя инструкциям, обратите внимание на то, что они принимают разные параметры.

Использование gofmt для форматирования кода

У нас были десятилетия бесконечных споров и споров о правильном формате программного обеспечения. Каждый язык имеет свои собственные идиомы и изменения, и многие имеют различные стандарты. Golang раз и навсегда покончил с этими бесконечными дебатами, выпустив форматтер, который гарантирует, что весь код идет в том же формате.

Иди не без его хулителей. Люди жалуются на то, что go fmt не настраивается и что он ставит скобки там, где они не нужны. Дураков. Стандарт не настраивается, и именно это мышление вызвало столько противоречий на любом другом языке. Go fmt это здорово. Он не только знает правильный формат, но и понимает код go. Он правильно выстраивает определения, правильно переносит операторы if, когда они становятся длиннее, и гарантирует, что ваш код полностью соответствует стандарту.

Самое приятное в этом то, что весь мой код полностью соответствует стандарту формата, и я никогда не читал политику формата go. Я просто пишу код и запускаю go fmt для этого кода, и мой код сразу же соответствует.

Предварительный просмотр изменений gofmt

Следующая команда покажет вам все изменения, которые gofmt сделает в формате diff.

$ gofmt path-to-code

Для данного файла он работает с этим файлом; данный каталог рекурсивно работает со всеми файлами .go в этом каталоге.

Отформатируйте ваш код

Следующая команда внесет изменения непосредственно в ваши исходные файлы.

$ gofmt path-to-code
or
$go fmt -l -w -s path-to-code

Вот пример изменений, которые gofmt сделает

 func (f *Filesystem) Files() []*File {
-   if len(f.files)<1 {f.captureFiles()}
+   if len(f.files) < 1 {
+       f.captureFiles()
+   }
    return f.files
 }

Для данного файла он работает с этим файлом; данный каталог рекурсивно работает со всеми файлами .go в этом каталоге.

Упрощенный режим

‘gofmt’ также может упростить код, где это необходимо, с помощью дополнительного флага -s Я обнаружил, что упрощение безопасно для использования и будет изменять код только тогда, когда это очевидно и понятно.

Вот пример изменений, которые упростит внесение.

-           final = append(final, first[start:len(first)]...)
+           final = append(final, first[start:]...)

Использование gofmt для рефакторинга кода

Gofmt гораздо мощнее, чем просто устранение аргументов о форматировании кода. Это также может реструктурировать ваш код. В отличие от использования традиционных инструментов Unix, таких как awk и grep, gofmt понимает код go и может использоваться для простой реструктуризации кода.

gofmt использует шаблоны для определения изменений, которые нужно внести в ваш код. Шаблоны устанавливаются в первой половине выражения, за которым следует ‘->’, а затем используется во второй половине выражения.

Используйте флаг -d вместо -w, чтобы проверить, что будет делать gofmt перед его запуском.

Примеры

Чтобы проверить файлы на наличие ненужных скобок (пример из документации):

gofmt -r '(a) -> a' -l *.go

diff hugolib/summary.go gofmt/hugolib/summary.go
    for i, line := range rstLines {
        if strings.HasPrefix(line, "<body>") {
-           rstLines = (rstLines[i+1 : len(rstLines)-3])
+           rstLines = rstLines[i+1 : len(rstLines)-3]
        }
    }

diff parser/parse_frontmatter_test.go gofmt/parser/parse_frontmatter_test.go
-       if (err == nil) != test.errIsNil {
+       if err == nil != test.errIsNil {

Переименуйте поле в структуре. Обратите внимание, что это не только меняет определение, но и в каждом месте, где установлено или указано значение

gofmt -r 'a.Info -> a.Information' -d ./

diff hugolib/site.go gofmt/hugolib/site.go

 func (s *Site) initializeSiteInfo() {
-   s.Info = SiteInfo{
+   s.Information = SiteInfo{

-   page.Site = s.Info
+   page.Site = s.Information

-   s.Info.Indexes = s.Indexes.BuildOrderedIndexList()
+   s.Information.Indexes = s.Indexes.BuildOrderedIndexList()

-   s.Info.LastChange = s.Pages[0].Date
+   s.Information.LastChange = s.Pages[0].Date

    for _, p := range s.Pages {
-       p.Site = s.Info
+       p.Site = s.Information
    }

-           n.Data["OrderedIndex"] = s.Info.Indexes[plural]
+           n.Data["OrderedIndex"] = s.Information.Indexes[plural]

    return &Node{
        Data: make(map[string]interface{}),
-       Site: s.Info,
+       Site: s.Information,
    }