JavaRush /Courses /Go SELF /gofmt formatting is part of the language

gofmt formatting is part of the language

Go SELF
Level 30, Lesson 0
Available

1. Introduction

When you’re just starting to program, formatting can feel like a “like/dislike” thing. One person loves 2 spaces, another 4; one puts braces “like in C”, another “like in JavaScript”, and a third writes as if they’re trying to save disk space in 1998.

In most languages this really does turn into endless (and slightly sad) arguments: where to put {, how many spaces, whether to align parameters, whether you can write if(x){y();} and why that makes you want to wash your hands afterwards.

Go looked at this and said: “Folks, let’s just agree once and for all.” That’s how gofmt appeared.

The Go ecosystem’s idea sounds roughly like this: code should look as if it has already been run through gofmt. This is not “advice”; it’s a cultural norm. In Go, an engineering habit even formed: if a tool rewrites code (refactoring, generation, auto-fixes), it leaves the result in gofmt form—so changes are about meaning, not spaces. In Go, this is seen as one of the “simplifying constraints”: less freedom in style means less noise in changes and fewer reasons to argue.

And the Go community also has a historically famous slogan in the “please don’t argue” category: go fmt your code—the idea is so important that it lives as a separate note/page in the official materials.

What gofmt is, in simple terms

In short: gofmt is a program that takes your Go code and brings it to a single canonical style.

But an important detail: gofmt formats not “with regexes”, but based on the syntax tree (the structure of Go code). That is, it first “understands” where blocks are, where expressions are, where function parameters are, where switch is, where composite literals are—and then it lays everything out neatly according to rules.

A simple takeaway follows from this: if the code compiles, gofmt can almost always bring it into a normal shape. And if the code doesn’t compile, gofmt is not obligated to guess what you meant (and that’s fair).

Determinism: same input → same output

One of the most underrated superpowers of gofmt is determinism. The word sounds like we’re about to summon the spirit of math analysis, but the meaning is very practical: if two people format the same code, the result will be identical.

Why do we need this?

Imagine you’re working on a team and making changes to a file task.go. You fixed the logic, and your teammate “just formatted the file their way”. In Git, you get a half-screen diff: lines moved, spaces changed, line breaks differ—and in that mess the truly important change hides like a cat under the couch when the vet shows up.

With gofmt, the diff becomes “about meaning”. In the Go world this is so important that it’s considered part of overall engineering discipline: tools and people agree on one style so they can discuss code, not spaces.

2. Mini demo: the same code before and after

First, let’s show a short example of “why it hurts to look at it”.

package main

import "fmt"

func main(){x:=1+2;if x>2{fmt.Println("ok")}else{fmt.Println("no")}}

The code compiles, but reading it is unpleasant: the if/else structure isn’t visible, the variable x got mixed with the condition, and the braces are so tight together it’s like they’re afraid of being alone.

After gofmt, the same meaning looks like this:

package main

import "fmt"

func main() {
	x := 1 + 2
	if x > 2 {
		fmt.Println("ok") // ok
	} else {
		fmt.Println("no") // no
	}
}

Notice: gofmt did not make the code “smarter”. It made the code more obvious. And that’s a huge difference.

3. What gofmt does and where it is especially noticeable

At this point it’s easy to expect too much from the tool: “if it’s so important, maybe it also fixes errors?”. No. gofmt is not a compiler and not magic.

Below is a small table to pin down the boundaries of responsibility.

Question Does gofmt do it? Comment
Sets indentation, spaces, and line breaks Yes This is the main job of gofmt.
Brings {} braces to the canonical style Yes Block style becomes predictable.
Does “pretty” alignment of struct fields Yes That’s why structs read almost like tables.
Changes program logic No Never. Even if “it would look nicer”.
Removes/adds import No It formats, but it does not manage a file’s dependencies.
Fixes compilation errors No If the code is syntactically broken, that’s your task.
“Optimizes” algorithms No Sadly, the “make it pretty and fast” button hasn’t been invented yet.

Why Go structs look “even”

One place where gofmt is especially noticeable is struct declarations. You already know how to model data via struct, so you’ve seen that Go code usually looks tidy.

Here is an example in canonical form (and it becomes this way specifically thanks to gofmt):

package main

type Task struct {
	ID   int
	Text string
	Done bool
}

func main() {}

The point here isn’t just “beauty”. This kind of alignment helps the brain scan fields quickly without stumbling. In large projects it genuinely speeds up code reading.

Example in a learning project: a console task tracker

So the examples aren’t “in a vacuum”, let’s keep developing our console task-tracker app. For now, let it be very simple: we store tasks in memory and can add and print them.

Suppose you wrote it like this (yes, it happens—especially when code is written “on the fly”):

package main

import "fmt"

type Task struct{ID int;Text string;Done bool}

func printTask(t Task){fmt.Printf("#%d %s done=%v\n",t.ID,t.Text,t.Done)}

Formally, Go will swallow this. But now imagine that in a week you add two more fields and three functions—the file will turn into mush.

After gofmt, the same code will become this:

package main

import "fmt"

type Task struct {
	ID   int
	Text string
	Done bool
}

func printTask(t Task) {
	fmt.Printf("#%d %s done=%v\n", t.ID, t.Text, t.Done) // #1 buy milk done=false
}

Notice a subtle but important effect: formatting makes the “shape” stable. And a stable shape makes it faster to notice mistakes in the “content”.

6. How to run gofmt regularly

When you work in an IDE, most of the time gofmt is enabled “under the hood”: on file save or via a hotkey the IDE formats the code. This is the ideal mode: you don’t think about formatting at all; it happens automatically.

But it’s important to be able to run gofmt manually as well—at least to understand the process and for “something went wrong” situations.

Formatting a specific file

You take a single file and bring it to the canonical style:

gofmt -w main.go

The -w flag means “rewrite the file in place” (write). Without -w, gofmt usually prints the result to stdout—handy for experiments, but in real life you almost always want -w.

See changes without rewriting the file

Sometimes you want to see “what would change”, but not touch the file automatically. For that, people often use diff mode:

gofmt -d main.go

This is useful when you want to understand what exactly gofmt is going to do, especially at the beginning.

7. Why gofmt saves time and how it fits into the process

In real projects, code almost always goes through review: someone else reads your changes and says “ok / not ok”. Beginners sometimes feel that review is “nitpicking”. In reality, review is a way not to miss a silly mistake and to learn to write more clearly.

But review becomes hell if the diff is full of noise.

Let’s imagine two commits.

The first one—you actually changed the logic:

if t.Done {
	fmt.Println("already done")
	return
}
t.Done = true

The second—you just rearranged spaces and line breaks. Now the reviewer sees a 200-line diff and spends attention on what isn’t important at all.

Go culture solves this radically: formatting is not discussed. Code simply must be in gofmt form. That’s why in the Go ecosystem gofmt is perceived not as “decoration”, but as a fundamental agreement that simplifies life for tools and for people.

A small diagram: where gofmt sits in the development loop

To lock this in, let’s represent a typical coding loop like this:

flowchart TD
    A[Write code] --> B[Run/save]
    B --> C[gofmt brings the file to canonical form]
    C --> D[Read the code]
    D --> E[Test/run]

The point is that gofmt sits very early: it stabilizes the shape so that later you work with the content.

Why “I want it my way” doesn’t take root in Go

Sometimes you get the urge to “tweak the style a bit”, for example:

  • align parameters with spaces across multiple lines “so it looks nice”;
  • place braces your own way;
  • make it “more compact” because “it’s clear anyway”.

In Go this almost always ends the same way: after some time the file is run through gofmt again, and your manual aesthetic edits disappear. And that’s normal.

At this point it’s useful to accept Go’s philosophy: style is not a playground for creativity. Let creativity be for architecture, algorithms, and good error messages. And let a robot place the spaces—it has, oddly enough, more emotional stamina for that.

8. Common mistakes when working with gofmt

Mistake No. 1: formatting “sometime later”.
A very common story: “I’ll finish writing first, then I’ll make it pretty.” The problem is that you are reading and debugging the code right now. If the code isn’t formatted, you make your life harder in the moment. It’s much cheaper to get used to the mode “wrote it—formatted automatically”.

Mistake No. 2: trying to align with spaces “for beauty”.
In Go this is almost always pointless: gofmt will bring it to the standard anyway. Worse, manual alignment often creates extra noise in change history: you changed one character in the middle of a line, and the diff starts looking like “everything shifted”.

Mistake No. 3: expecting gofmt to fix compilation errors.
gofmt doesn’t fix syntax for you. If you forgot a } or a comma in a literal, you must make the code correct first, and only then format it.

Mistake No. 4: confusing formatting with code quality.
Formatted code can still be bad code. gofmt makes the shape neat, but it does not replace clear names, good decomposition, or tests. It’s like a clean shirt: it doesn’t make you smarter, but it greatly increases the chances that people will talk to you seriously.

Mistake No. 5: taking gofmt as a personal insult to your taste.
Yes, the style is fixed. Yes, sometimes you’ll want it to be “just a little different”. That passes. Usually somewhere between the third and fifth file that you can read without embarrassment a month after writing it.

1
Task
Go SELF, level 30, lesson 0
Locked
Strict Traffic Light
Strict Traffic Light
1
Task
Go SELF, level 30, lesson 0
Locked
Task card
Task card
1
Task
Go SELF, level 30, lesson 0
Locked
Polite Greeting
Polite Greeting
1
Task
Go SELF, level 30, lesson 0
Locked
General style
General style
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION