Modulelessen (1/5)
Geavanceerde 'fmt'
Het pakket fmt is de toegangspoort tot alle tekstuele I/O in Go. Als u het goed kent, betekent dit dat u leesbare logboeken, informatieve fouten en idiomatische opmaak van waarden schrijft zonder toevlucht te nemen tot externe bibliotheken.
De vier gezinnen
fmt onthult functies in vier families, onderscheiden door een voorvoegsel:
Print*→ schrijft naaros.Stdout(Print,Println,Printf).Fprint*→ schrijft naar eenio.Writer(Fprintln(os.Stderr, ...),Fprintf(file, ...)).Sprint*→ retourneert een tekenreeks zonder af te drukken (Sprintf,Sprintln).Errorf→ bouwt een geformatteerdeerror.
fmt.Println("hello") // stdout
fmt.Fprintln(os.Stderr, "boom") // stderr
s := fmt.Sprintf("[%d]", 42) // "[42]"
err := fmt.Errorf("parse %q: %w", in, base) // wrapped errorHet verschil tussen Print en Println is alleen de spatie tussen de argumenten en de afsluitende nieuwe regel: Println voegt altijd \n toe, Print niet, Printf volgt het formaat.
Belangrijkste werkwoorden
| Werkwoord | Wat het doet |
|---|---|
%v | Standaardwaarde (roept String() aan indien geïmplementeerd). |
%+v | Structuur met veldnamen. |
%#v | Go-syntaxis (handig voor foutopsporing en snapshots). |
%T | Dynamisch type van de waarde. |
%d | Geheel getal met grondtal 10. |
%b %o %x %X | Binair, octaal, hexadecimaal (kleine letters/hoofdletters). |
%f %e %g | Drijvende komma: vast, exponentieel, compact. |
%s | Tekenreeks (of error/Stringer). |
%q | Go-stijl geciteerde string (inclusief ontsnappingen). |
%c | Unicode-teken (rune). |
%p | Aanwijzer in hexadecimaal. |
%w | Foutverwerking (alleen binnen 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.PointBreedte, precisie, vlaggen
Numerieke werkwoorden en tekenreekswerkwoorden accepteren breedte en precisie:
%6d→ minimale breedte 6, linker opvulling met spaties.%-6d→ breedte 6, rechter opvulling (vlag-).%06d→ breedte 6, opvulling met0(vlag0).%.2f→ precisie 2 decimalen.%8.2f→ breedte 8, precisie 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|Voor uitgelijnde tabellen is de vaste breedte + %-...s voor tekstkolommen het eenvoudigste patroon voordat u naar text/tabwriter gaat.
%w en foutafwikkeling
%w is speciaal: het werkt alleen binnen fmt.Errorf en behoudt de oorspronkelijke fout in de keten, zodat errors.Is en errors.As er doorheen kunnen lopen.
if _, err := os.Open(path); err != nil {
return fmt.Errorf("read config %q: %w", path, err)
}Als u %v gebruikt in plaats van %w wordt de foutmelding afgedrukt maar wordt de keten verbroken: niet uitpakken, geen errors.Is. Regel: als u wilt dat de beller het type of de identiteit van de fout kan onderscheiden, gebruikt u %w (slechts één per Errorf).
Oefeningen
Gebruik fmt.Sprintf om de tekenreeks '[42]' te formatteren op basis van het gehele getal 42, en druk deze vervolgens af.
Oplossing beschikbaar na 3 pogingen
Print de struct p met het werkwoord %+v (deze moet de veldnamen bevatten).
Oplossing beschikbaar na 3 pogingen
Welk werkwoord, gebruikt in fmt.Errorf, bewaart de foutketen voor fouten.Is/As?
err := fmt.Errorf("read %q: ???", path, base)