Lezioni del modulo (1/5)
`fmt` avanzato
Il pacchetto fmt è la porta d'ingresso di tutti gli I/O testuali in Go. Conoscerlo bene significa scrivere log leggibili, errori informativi e formattare valori in modo idiomatico senza ricorrere a librerie esterne.
Le quattro famiglie
fmt espone funzioni in quattro famiglie, distinte dal prefisso:
Print*→ scrive suos.Stdout(Print,Println,Printf).Fprint*→ scrive su unio.Writerqualsiasi (Fprintln(os.Stderr, ...),Fprintf(file, ...)).Sprint*→ restituisce una stringa senza stampare (Sprintf,Sprintln).Errorf→ costruisce unerrorformattato.
fmt.Println("hello") // stdout
fmt.Fprintln(os.Stderr, "boom") // stderr
s := fmt.Sprintf("[%d]", 42) // "[42]"
err := fmt.Errorf("parse %q: %w", in, base) // error wrappatoLa differenza fra Print e Println è solo lo spazio fra gli argomenti e il newline finale: Println aggiunge sempre \n, Print no, Printf segue il formato.
Verbi principali
| Verbo | Cosa fa |
|---|---|
%v | Valore di default (richiama String() se implementato). |
%+v | Struct con nomi dei campi. |
%#v | Sintassi Go (utile per debug e snapshot). |
%T | Tipo dinamico del valore. |
%d | Intero in base 10. |
%b %o %x %X | Binario, ottale, esadecimale (minuscolo/maiuscolo). |
%f %e %g | Floating point: fisso, esponenziale, compatto. |
%s | Stringa (o error/Stringer). |
%q | Stringa quotata stile Go (escape inclusi). |
%c | Carattere Unicode (rune). |
%p | Puntatore in esadecimale. |
%w | Wrap di error (solo dentro Errorf). |
type Point struct{ X, Y int }
p := Point{1, 2}
fmt.Printf("%v\n", p) // {1 2}
fmt.Printf("%+v\n", p) // {X:1 Y:2}
fmt.Printf("%#v\n", p) // main.Point{X:1, Y:2}
fmt.Printf("%T\n", p) // main.PointLarghezza, precisione, flag
I verbi numerici e di stringa accettano larghezza e precisione:
%6d→ larghezza minima 6, padding di spazi a sinistra.%-6d→ larghezza 6, padding a destra (flag-).%06d→ larghezza 6, padding con0(flag0).%.2f→ precisione 2 cifre decimali.%8.2f→ larghezza 8, precisione 2.
fmt.Printf("|%6d|\n", 42) // | 42|
fmt.Printf("|%-6d|\n", 42) // |42 |
fmt.Printf("|%06d|\n", 42) // |000042|
fmt.Printf("|%8.2f|\n", 3.14)// | 3.14|Per tabelle allineate, larghezza fissa + %-...s per le colonne testuali è il pattern più semplice prima di passare a text/tabwriter.
%w e wrapping degli errori
%w è speciale: funziona solo dentro fmt.Errorf e conserva l'errore originale nella catena, in modo che errors.Is ed errors.As possano risalirla.
if _, err := os.Open(path); err != nil {
return fmt.Errorf("read config %q: %w", path, err)
}Usare %v invece di %w stampa il messaggio dell'errore ma rompe la catena: niente unwrap, niente errors.Is. Regola: se vuoi che il chiamante possa distinguere il tipo o l'identità dell'errore, usa %w (uno solo per Errorf).
Esercizi
Usa fmt.Sprintf per formattare la stringa '[42]' a partire dall'intero 42, poi stampala.
Soluzione disponibile dopo 3 tentativi
Stampa la struct p con il verbo %+v (deve includere i nomi dei campi).
Soluzione disponibile dopo 3 tentativi
Quale verbo, usato in fmt.Errorf, preserva la catena di errori per errors.Is/As?
err := fmt.Errorf("read %q: ???", path, base)