Code Formatting

Learn about code formatting in Go.

gofmt

Much of Go code formatting is forced upon you by the gofmt tool. gofmt makes automatic changes to source files, such as sorting import declarations and applying indentation. It’s the best thing since sliced bread as it saves man-years of developers arguing about things that hardly matter. For instance, it uses tabs for indentation and spaces for alignment, which is the end of that story.

You are free not to use the gofmt tool at all, but if you use it, you can’t configure it to a particular formatting style. The tool provides zero code formatting options, and that’s the point - to provide one “good enough” uniform formatting style. It might be nobody’s favorite style, but Go developers decided that uniformity is better than perfection.

Some benefits of shared style and automatic code formatting are:

  • No time needs to be spent in code reviews on formatting issues.
  • It saves you from colleagues with obsessive-compulsive disorder about where the opening brace should go or what should be used for indentation. All that passion and energy can be used more productively.
  • Code is easier to write: Minor formatting details are sorted for you.
  • Code is easier to read: You don’t need to parse someone else’s unfamiliar formatting style mentally.

Most popular IDEs have plugins for Go that run gofmt automatically when saving a source file.

Third-party tools such as goformat allow custom code-style formatting in Go if you really need it.

Long lines

gofmt will not try to break up long lines of code. There are third-party tools such as golines that do that.

Opening bracket

An opening bracket must be placed at the end of the line in Go. Interestingly this is not enforced by gofmt, but rather is a side effect of how Go lexical analyzer is implemented. With or without gofmt, an opening bracket can’t be placed on a new line:

package main
// missing function body
func main()
// syntax error: unexpected semicolon or newline before {
{
}

The right way to use brackets in Go is given below.

package main
// all good!
func main() {
}

Commas in multi-line declarations

Go requires a comma before a new line when initializing a slice, array, map, or struct. Trailing commas are allowed in many languages and encouraged in some style guides. In Go, they’re mandatory. That’s how lines can be rearranged or new lines can be added without modifying unrelated lines. This results in lesser noise in code review diffs.

package main
func main(){
// all of these are OK
a := []int{1, 2}
b := []int{1, 2,}
c := []int{
1,
2}
d := []int{
1,
2,
}
// syntax error without trailing comma
e := []int{
1,
// syntax error: unexpected newline, expecting comma or }
2
}
}

A similar kind of behavior is observed with structs:

package main
func main(){
type s struct {
One int
Two int
}
f := s{
One: 1,
// syntax error: unexpected newline, expecting comma or }
Two: 2
}
}