Direct naar de hoofdinhoud
Module 8 · Les 1 van 536/50 in de cursus~10 min
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 naar os.Stdout (Print, Println, Printf).
  • Fprint* → schrijft naar een io.Writer (Fprintln(os.Stderr, ...), Fprintf(file, ...)).
  • Sprint* → retourneert een tekenreeks zonder af te drukken (Sprintf, Sprintln).
  • Errorf → bouwt een geformatteerde error.
Go
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 error

Het 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

WerkwoordWat het doet
%vStandaardwaarde (roept String() aan indien geïmplementeerd).
%+vStructuur met veldnamen.
%#vGo-syntaxis (handig voor foutopsporing en snapshots).
%TDynamisch type van de waarde.
%dGeheel getal met grondtal 10.
%b %o %x %XBinair, octaal, hexadecimaal (kleine letters/hoofdletters).
%f %e %gDrijvende komma: vast, exponentieel, compact.
%sTekenreeks (of error/Stringer).
%qGo-stijl geciteerde string (inclusief ontsnappingen).
%cUnicode-teken (rune).
%pAanwijzer in hexadecimaal.
%wFoutverwerking (alleen binnen Errorf).
Go
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.Point

Breedte, 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 met 0 (vlag 0).
  • %.2f → precisie 2 decimalen.
  • %8.2f → breedte 8, precisie 2.
Go
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.

Go
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

Oefening#go.m8.l1.e1
Pogingen: 0Laden…

Gebruik fmt.Sprintf om de tekenreeks '[42]' te formatteren op basis van het gehele getal 42, en druk deze vervolgens af.

Editor laden…

Oplossing beschikbaar na 3 pogingen

Oefening#go.m8.l1.e2
Pogingen: 0Laden…

Print de struct p met het werkwoord %+v (deze moet de veldnamen bevatten).

Editor laden…

Oplossing beschikbaar na 3 pogingen

Quiz#go.m8.l1.e3
Klaar

Welk werkwoord, gebruikt in fmt.Errorf, bewaart de foutketen voor fouten.Is/As?

Go
err := fmt.Errorf("read %q: ???", path, base)
Antwoordmogelijkheden