1. Introduzione
Quando inizi a programmare, sembra che la formattazione sia una questione di «mi piace / non mi piace». Uno ama 2 spazi, un altro 4, il terzo mette le parentesi «come in C», il quarto «come in JavaScript», e il quinto scrive in modo da risparmiare spazio sul disco rigido nel 1998.
Nella maggior parte dei linguaggi questo si trasforma davvero in discussioni infinite (e un po' tristi): dove mettere {, quanti spazi usare, se allineare i parametri, se si puo` scrivere if(x){y();} e perche` dopo viene voglia di lavarsi le mani.
Go ha guardato tutto questo e ha detto: «Ragazzi, decidiamo una volta per tutte». Così e` nato gofmt.
L'idea dell'ecosistema Go suona piu` o meno cosi`: il codice deve sembrare come se fosse gia` passato attraverso gofmt. Non e` un «consiglio», ma una norma culturale. In Go si e` persino formata un'abitudine ingegneristica: se uno strumento riscrive il codice (refactoring, generazione, correzioni automatiche), lascia il risultato in stile gofmt — cosi` le modifiche riguardano solo il significato, non gli spazi. In Go questo viene visto come una delle «limitazioni che semplificano»: meno liberta` nello stile, meno rumore nei cambiamenti e meno motivi per litigare.
E poi la comunita` Go ha uno slogan storicamente noto del tipo «per favore, non litigate»: go fmt your code — un'idea cosi` importante da vivere come nota/pagina separata nei materiali ufficiali.
Che cos'e` gofmt in parole semplici
In breve: gofmt e` un programma che prende il tuo codice Go e lo porta a uno stile canonico uniforme.
Ma c'e` un dettaglio importante: gofmt formatta non «con le regexp», bensì con l'ausilio dell'albero sintattico (la struttura del codice Go). In pratica, prima «capisce» dove sono i blocchi, le espressioni, i parametri della funzione, dove si trova switch, dove sono i letterali composti — e poi dispone tutto con cura secondo le regole.
Da qui deriva una morale semplice: se il codice compila, gofmt quasi sempre puo` portarlo a un aspetto normale. Se invece il codice non compila, gofmt non e` tenuto a indovinare cosa volevi scrivere (ed e` giusto così).
Determinismo: stesso input → stesso output
Uno dei superpoteri piu` sottovalutati di gofmt e` il determinismo. Questa parola suona come se stessimo per evocare lo spirito dell'analisi matematica, ma il senso e` molto pratico: se due persone formattano lo stesso codice, il risultato sara` identico.
Perche` serve?
Immagina di lavorare in un team e fare modifiche nel file task.go. Hai corretto la logica, e il tuo collega «ha solo formattato il file a modo suo». In Git otterrai un diff lungo mezza schermata: le righe si sono spostate, gli spazi sono cambiati, gli a capo sono diversi — e in mezzo a tutto questo rumore la modifica davvero importante si nasconde come un gatto sotto il divano nel momento in cui arriva il veterinario.
Con gofmt il diff diventa «sul significato». Nel mondo Go questo e` cosi` importante che viene considerato parte della disciplina ingegneristica comune: strumenti e persone si accordano su uno stile unico, così da discutere il codice e non gli spazi.
2. Mini demo: lo stesso codice prima e dopo
Prima mostriamo un breve esempio di «perche` fa male agli occhi».
package main
import "fmt"
func main(){x:=1+2;if x>2{fmt.Println("ok")}else{fmt.Println("no")}}
Il codice compila, ma e` spiacevole da leggere: la struttura if/else non si vede, la variabile x si e` mescolata alla condizione, e le parentesi stanno così vicine come se avessero paura della solitudine.
Dopo gofmt lo stesso significato appare così:
package main
import "fmt"
func main() {
x := 1 + 2
if x > 2 {
fmt.Println("ok") // ok
} else {
fmt.Println("no") // no
}
}
Nota bene: gofmt non ha reso il codice «piu` intelligente». Ha reso il codice piu` evidente. E questa e` una differenza enorme.
3. Cosa fa gofmt e dove si nota di piu`
Qui e` facile aspettarsi troppo dallo strumento: «se e` così importante, magari corregge anche gli errori?». No. gofmt non e` un compilatore e non e` magia.
Qui sotto c'e` una piccola tabella per fissare i confini di responsabilita`.
| Domanda | gofmt lo fa? | Commento |
|---|---|---|
| Imposta indentazione, spazi e a capo | Sì | Questo e` il lavoro principale di gofmt. |
| Porta le parentesi graffe {} al canone | Sì | Lo stile dei blocchi diventa prevedibile. |
| Fa un allineamento «bello» dei campi struct | Sì | Per questo le strutture si leggono quasi come tabelle. |
| Cambia la logica del programma | No | Mai. Anche se «così e` piu` bello». |
| Rimuove / aggiunge import | No | Formatta, ma non gestisce le dipendenze del file. |
| Corregge gli errori di compilazione | No | Se il codice e` sintatticamente rotto, e` un tuo compito. |
| «Ottimizza» gli algoritmi | No | Purtroppo il pulsante «rendilo bello e veloce» non e` stato ancora inventato. |
Perche` le strutture Go sembrano «uniformi»
Uno dei punti in cui gofmt si nota di piu` e` la definizione delle strutture. Hai gia` imparato a modellare i dati con struct, quindi hai visto che il codice Go di solito appare ordinato.
Ecco un esempio in forma canonica (e lo diventa proprio grazie a gofmt):
package main
type Task struct {
ID int
Text string
Done bool
}
func main() {}
Il senso qui non e` solo la «bellezza». Un tale allineamento aiuta il cervello a scansionare i campi rapidamente, senza inciampare. Nei progetti grandi questo accelera davvero la lettura del codice.
Esempio su un progetto didattico: una to-do list da terminale
Per non restare «nel vuoto», continuiamo a sviluppare la nostra applicazione da terminale per le attivita`. Supponiamo che per ora sia molto semplice: teniamo le attivita` in memoria e sappiamo aggiungere e stampare.
Mettiamo che tu abbia scritto così (sì, succede — soprattutto quando il codice viene scritto «sul ginocchio»):
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)}
Formalmente Go lo digerisce. Ma ora immagina che tra una settimana aggiungi altri due campi e tre funzioni — il file diventera` una poltiglia.
Dopo gofmt lo stesso codice diventera` così:
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
}
Nota un effetto sottile ma importante: la formattazione rende stabile la «forma». E una forma stabile ti permette di notare piu` velocemente gli errori nel «contenuto».
6. Come eseguire gofmt regolarmente
Quando lavori in un IDE, molto spesso gofmt e` attivo «sotto il cofano»: al salvataggio del file o con una scorciatoia, l'IDE formatta il codice. E` la modalita` ideale: non pensi affatto alla formattazione, avviene automaticamente.
Ma e` importante saper avviare gofmt anche a mano — almeno per capire il processo e per le situazioni in cui «qualcosa e` andato storto».
Formattare un file specifico
Prendi un file e portalo al canone:
gofmt -w main.go
Il flag -w significa «riscrivi il file sul posto» (write). Senza -w gofmt in genere stampa il risultato su stdout — comodo per esperimenti, ma nella vita reale quasi sempre si vuole proprio -w.
Vedere le modifiche senza riscrivere il file
A volte vuoi vedere «che cosa cambierebbe», ma senza toccare automaticamente il file. Per questo si usa spesso la modalita` diff:
gofmt -d main.go
Questo e` utile quando vuoi capire che cosa esattamente gofmt sta per fare, soprattutto all'inizio.
7. Perche` gofmt fa risparmiare tempo e come si inserisce nel processo
Nei progetti reali il codice passa quasi sempre da una revisione: qualcun altro legge le tue modifiche e dice «ok / non ok». Ai principianti a volte sembra che la revisione siano «puntigliosita`». In realta` la revisione e` un modo per non lasciarsi sfuggire un errore stupido e imparare a scrivere in modo piu` chiaro.
Ma la revisione diventa un inferno se nel diff c'e` troppo rumore.
Immagina due commit.
Il primo — hai davvero cambiato la logica:
if t.Done {
fmt.Println("already done")
return
}
t.Done = true
Il secondo — hai solo spostato spazi e a capo. Ora il reviewer vede un diff di 200 righe e spreca attenzione su qualcosa che non e` affatto importante.
La cultura Go risolve il problema in modo radicale: la formattazione non si discute. Il codice deve semplicemente essere in stile gofmt. Per questo nell'ecosistema Go gofmt e` percepito non come «ornamento», ma come un accordo fondamentale che semplifica la vita sia agli strumenti sia alle persone.
Piccolo schema: il posto di gofmt nel ciclo di sviluppo
Per fissare il concetto, immaginiamo il tipico ciclo di lavoro sul codice così:
flowchart TD
A[Scriviamo il codice] --> B[Lo eseguiamo / salviamo]
B --> C[gofmt porta il file al canone]
C --> D[Leggiamo il codice con gli occhi]
D --> E[Testiamo / eseguiamo]
Il punto e` che gofmt entra in gioco molto presto: rende stabile la forma, così poi lavori sul contenuto.
Perche` «lo voglio a modo mio» in Go non attecchisce bene
A volte nasce il desiderio di «correggere un po' lo stile», per esempio:
- allineare con gli spazi i parametri su piu` righe «perche` sia bello»;
- mettere le parentesi a modo proprio;
- rendere tutto «piu` compatto» perche` «si capisce già».
In Go questo quasi sempre finisce allo stesso modo: dopo un po' il file viene di nuovo passato attraverso gofmt, e le tue correzioni estetiche manuali scompaiono. E va bene così.
In questo punto e` utile accettare la filosofia di Go: lo stile non e` un campo per la creativita`. Lasciamo la creativita` all'architettura, agli algoritmi e a buoni messaggi di errore. Gli spazi li metta pure il robot — incredibilmente, per questo ha piu` forza d'animo.
8. Errori tipici quando si lavora con gofmt
Errore n. 1: formattare «piu` tardi, un giorno».
Storia molto comune: «prima finisco, poi sistemo la presentazione». Il problema e` che tu il codice lo leggi e lo debugg i adesso. Se il codice non e` formattato, ti complichi la vita proprio sul momento. Molto meglio abituarsi alla modalita` «ho scritto — si e` formattato automaticamente».
Errore n. 2: cercare di allineare manualmente con gli spazi «per bellezza».
In Go questo e` quasi sempre inutile: gofmt riporta comunque allo standard. Peggio ancora, l'allineamento manuale spesso crea rumore inutile nella storia delle modifiche: hai cambiato un solo carattere nel mezzo di una riga, e il diff sembra che «si sia spostato tutto».
Errore n. 3: aspettarsi che gofmt corregga gli errori di compilazione.
gofmt non sistema la sintassi al posto tuo. Se hai dimenticato } o una virgola in un letterale, prima bisogna rendere il codice corretto e solo dopo formattarlo.
Errore n. 4: confondere formattazione e qualita` del codice.
Un codice formattato puo` essere comunque cattivo. gofmt rende la forma ordinata, ma non sostituisce ne` nomi chiari, ne` una buona decomposizione, ne` i test. E` come una camicia pulita: non ti rende piu` intelligente, ma aumenta molto le probabilita` che ti prendano sul serio.
Errore n. 5: prendere gofmt come un'offesa personale al proprio gusto.
Sì, lo stile e` fisso. Sì, a volte vorrai «un po' diverso». Passa. Di solito tra il terzo e il quinto file che rileggi senza vergogna un mese dopo averlo scritto.
GO TO FULL VERSION