gofmt ends the style wars
PHP's style history is a saga. PSR-1, then PSR-2, then PSR-12, then PER Coding Style. PHP_CodeSniffer, PHP-CS-Fixer, Laravel Pint with its own presets. A .php-cs-fixer.dist.php in every repo, each one slightly different, and at least one pull request thread per year about whether the opening brace of a closure belongs on the same line.
Go skipped all of that. It ships with gofmt, a formatter with no configuration at all. Not "sensible defaults": no options. Every Go file in every Go project is formatted the same way, by the same tool.
What gofmt decides for you
- Tabs for indentation, spaces for alignment. The tabs-vs-spaces war ended in 2009. Tabs won, and nobody had to fight. Your editor can display a tab at whatever width you like.
- Braces, spacing and blank lines around imports and declarations.
- Alignment of struct fields, comments and composite literals, which PHP devs normally line up by hand or with a fixer rule.
- No line length limit. Wrap long lines yourself where it helps readability; gofmt won't do it for you, and won't complain either.
There's a Go proverb about it: gofmt's style is no one's favourite, yet gofmt is everyone's favourite. You give up a little personal taste, and in exchange every codebase you open reads like your own.
In practice, you never run it
Every Go editor setup (VS Code's Go extension, GoLand, Neovim with gopls) runs gofmt when you save. Most people actually use goimports, which is gofmt plus adding and removing imports for you. That makes the "unused import" error from 0.2 far less annoying.
In CI, gofmt -l . lists any files that aren't formatted, so you can fail the build on them. In this course, the Format button (or Ctrl+S) runs gofmt on your code.
Formatting that tells you something
gofmt doesn't just tidy whitespace. It also uses spacing to show operator precedence: it keeps spaces around lower-precedence operators and removes them around higher ones.
total := travel+dwell * stops // looks like (travel+dwell) * stops total := travel + dwell*stops // after gofmt: it never was
(:= declares a variable and assigns to it in one go. Unit 1 covers it; for now, read it as $total =.)
Mind the gap
Spacing in PHP is decoration: $travel+$dwell * $stops and $travel + $dwell*$stops read differently but mean the same thing, and nothing points it out. In Go, gofmt makes the spacing match what the code actually does. If the formatted version surprises you, believe the formatted version, and add parentheses.
What gofmt won't do
It only formats code that parses: a syntax error means no formatting. It won't rename get_user_name to userName, reorder your logic, or fix bugs. go vet (0.3) and linters (5.7) handle more of that. The formatter's job is to make sure you never discuss whitespace in code review again.
Recap
- gofmt is built in and has no configuration: tabs, spacing, braces and alignment are decided for you.
- Editors run it (or goimports) on save; CI checks with
gofmt -l .. - gofmt's spacing shows precedence:
a + b*c. If the formatted code surprises you, it's telling you something.