SoFunction
Updated on 2025-03-03

Golang uses gofumpt for code formatting

From the beginning when we write Go code and applications, we will be taught by various official and folk tutorials, and even the IDEs to teach us that we must be equipped with a gofmt tool. He is able to format the code of Go programs. Tab characters are used to represent indentation and blanks are used to represent alignment.

This solves one of the long-standing problems of programmers, the standardization problem in code format. Effectively improves the friendliness of Go code reading and reduces **** among colleagues. Very worthy of recognition.

But sometimes, I still see some bad code and always feel that gofmt is not formatted enough.

Today I will share with you a more ruthless tool I found: gofumpt. The examples are mainly based on official documents.

Stronger formatting: gofumpt

Gofumpt will execute stricter Go format specifications than gofmt. Also ensure backward compatibility.

This tool is a gofmt branch of Go 1.21 and requires Go 1.20 or higher. It can directly replace existing Go code formatting, that is, running gofmt after gofumpt will not cause any new changes.

Installation command:

$ go install /gofumpt@latest

Execute the command:

$ gofumpt -l -w .

Check the corresponding formatted file and it will take effect.

Here are some more specific examples of the difference between gofmt and gofumpt. It can help everyone identify the differences.

There are no empty lines after the assignment operator

Originally formatted by gofmt:

func foo() string {
 foo :=
  "The brain is frying fish!"
 return foo
}

After formatting to gofumpt:

func foo() string {
 foo := "The brain is frying fish!"
 return foo
}

There are no empty lines around the function body

Originally formatted by gofmt:

func foo() {

 println("Frying fish into your brain!")

}

After formatting to gofumpt:

func foo() {
 println("Frying fish into your brain!")
}

Functions should be separated ) { , indentation helps improve readability

Originally formatted by gofmt:

func foo(s string,
 i int) {
 println("Fried fish!!!")
}

// Using blank chariots will be slightly better, but still not good enoughfunc bar(s string,
 i int) {

 println("Fried fish!!!")
}

After formatting to gofumpt:

func foo(s string,
 i int,
) {
 println("Fried fish!!!")
}

func bar(s string,
 i int,
) {
 println("Fried fish!!!")
}

There are no empty lines around separate statements (or comments) in code blocks

Originally formatted by gofmt:

if err != nil {

 return err
}

After formatting to gofumpt:

if err != nil {
 return err
}

No empty lines before simple error check

Originally formatted by gofmt:

foo, err := processFoo()

if err != nil {
 return err
}

After formatting to gofumpt:

foo, err := processFoo()
if err != nil {
 return err
}

Compound literals should use line breaks uniformly

Originally formatted by gofmt:

var ints = []int{1, 2,
 3, 4}

var matrix = [][]int{
 {1},
 {2}, {
  3,
 },
}

After formatting to gofumpt:

var ints = []int{
 1, 2,
 3, 4,
}

var matrix = [][]int{
 {1},
 {2},
 {
  3,
 },
}

Empty field list should use a single line

Originally formatted by gofmt:

var V interface {
} = 3

type T struct {
}

func F(
)

After formatting to gofumpt:

var V interface{} = 3

type T struct{}

func F()

Standard library imports must be grouped separately at the top

Originally formatted by gofmt:

import (
 "/bar"

 "io"

 "io/ioutil"
)

After formatting to gofumpt:

import (
 "io"
 "io/ioutil"

 "/bar"
)

A short case clause should occupy one line

Originally formatted by gofmt:

switch c {
case 'a', 'b',
 'c', 'd':
}

After formatting to gofumpt:

switch c {
case 'a', 'b', 'c', 'd':
}

Multi-line top-level declarations must be separated by blank lines

Originally formatted by gofmt:

func foo() {
 println("Fry fish!")
}
func bar() {
 println("Fry fish!")
}

After formatting to gofumpt:

func foo() {
 println("Fry fish!")
}

func bar() {
 println("Fry fish!")
}

A single var declaration should not be grouped using brackets

Originally formatted by gofmt:

var (
 foo = "Fry fish!"
)

After formatting to gofumpt:

var foo = "Fry fish!"

Continuous top-level declarations should be grouped

Originally formatted by gofmt:

var nicer = "x"
var with = "y"
var alignment = "z"

After formatting to gofumpt:

var (
 nicer     = "x"
 with      = "y"
 alignment = "z"
)

Simple var declaration statements should use short assignments

Originally formatted by gofmt:

var s = "Frying fish into the brain"

After formatting to gofumpt:

s := "Frying fish into the brain"

The -s code simplifies tagging is enabled by default.

Comments for non-Go directives should start with spaces

Originally formatted by gofmt:

//go:noinline

//Foo is awesome.
func Foo() {}

After formatting to gofumpt:

//go:noinline

// Foo is awesome.
func Foo() {}

VSCode configuration

It can be configured directly in the IDE. For example, VSCode can be configured as follows:

{
    "": true,
    "gopls": {
        "": true,
    },
}

It can be used directly in Go applications.

Summarize

I had a friend who took over an old project before. That classmate has almost no code-specific style. It all depends on gofmt to help him format it.

But you also see that gofmt only does the most basic ones. At this time, gofumpt is very good if there is a stricter Go code formatting tool. (This classmate needs to be guided, but it is easy to get into trouble)

Like the aforementioned "multi-line top-level declarations must be separated by blank lines" is very valuable. I have really seen a large pile of squeezing together without empty lines. It looks very uncomfortable.

This is the article about Golang's code formatting using gofumpt. For more related Go gofumpt formatting code content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!