/ Kapitel

Das fmt-Paket Formatierte I/O

Das fmt-Paket ist Gos Schweizer Taschenmesser für formatierte Ausgabe und Eingabe. Diese Übersicht erklärt die drei großen Funktionsfamilien (Print, Fprint, Sprint) plus Errorf, Scan und die Interfaces Stringer, GoStringer, Formatter — und verlinkt auf die Detail-Seiten zu jeder Funktion.

Das fmt-Paket bündelt Gos formatierte Ein- und Ausgabe: vom schnellen Println im Hello-World bis zum produktionsreifen Error-Wrapping mit %w. Es ist eines der ersten Pakete, das jeder Go-Entwickler kennenlernt — und gleichzeitig eines der am häufigsten unterschätzten. Wer die Format-Verben beherrscht, das Stringer-Interface implementiert und Errorf mit %w korrekt einsetzt, schreibt Code, der sich später wie selbsterklärendes Englisch liest.

Dieser Bereich ist als Referenz aufgebaut: Die Übersicht erklärt die drei Funktionsfamilien und ihre gemeinsamen Konzepte, jede einzelne Funktion und jeder Typ haben eine eigene Detail-Seite mit Signatur, ausführlicher Erklärung, Beispielen und Stolperfallen. Wer das Paket zum ersten Mal lernt, liest hier von oben nach unten. Wer eine konkrete Funktion nachschlagen will, springt direkt zur passenden Seite. Offizielle Referenz: pkg.go.dev/fmt.

Drei Funktionsfamilien plus Errorf

Die zwölf Print-Funktionen ergeben sich aus drei orthogonalen Dimensionen: Ziel (Stdout, Writer, String), Format (positional vs. Format-String) und Newline-Verhalten. Diese systematische Komposition macht das API auf den ersten Blick sperrig, aber sobald man das Muster verinnerlicht hat, leitet man jede Variante aus dem Namen ab.

FamilieZielBeispiel
Printos.Stdoutfmt.Println("hi")
Fprintio.Writerfmt.Fprintln(os.Stderr, "err")
Sprintstrings := fmt.Sprintf("%d", n)
Append (Go 1.19+)[]bytebuf = fmt.Appendf(buf, "%d", n)
Errorferrorreturn fmt.Errorf("op: %w", err)
Scanvon Stdin/Reader/Stringfmt.Sscanf(s, "%d", &n)

Innerhalb jeder Familie gibt es drei Newline-Varianten: ohne Suffix (positional, kein Newline), mit ln-Suffix (positional, Newline am Ende), mit f-Suffix (Format-String, kein Newline). Die einzige Ausnahme ist Errorf, das per Konvention keinen Newline anhängt — Errors sollen ohne \n enden, weil Logger und Wrapper sich selbst um die Zeilentrennung kümmern.

Format-Verben — der Kern des Pakets

Die Format-Verben sind das Herzstück von Printf und Verwandten. Jedes Verb gehört zu einer Typklasse: generelle Verben wirken auf jeden Wert, Integer-Verben nur auf Ganzzahlen, Float-Verben nur auf Fließkommazahlen, String-Verben auf Strings und Byte-Slices. Die Auswahl ist überschaubar, aber sehr ausdrucksstark, sobald man sie auswendig kennt.

Die wichtigsten Verben in einem Satz: %v für die Default-Darstellung, %+v für Structs mit Feldnamen, %#v für die Go-Syntax-Repräsentation, %T für den konkreten Typ, %d für Dezimal-Integer, %x für Hex, %f für Floats, %s für Strings, %q für gequotete Strings, %w für Error-Wrapping, %t für Booleans, %c für Runes, %p für Pointer. Eine vollständige Tabelle mit allen Verben und Modifikatoren findet sich auf der eigenen Format-Verben-Seite.

Custom-Formatierung über Interfaces

fmt ruft beim Formatieren automatisch passende Interface-Methoden auf, sofern der Wert sie implementiert. Das macht eigene Typen integrierbar, ohne dass Aufrufer wissen müssen, wie sie zu formatieren sind. Drei Interfaces sind dafür relevant:

  • fmt.Stringer — die String() string-Methode. Wird von %s, %v, %q automatisch genutzt. Standardlösung für lesbare Repräsentation von Custom-Typen.
  • fmt.GoStringer — die GoString() string-Methode. Wird nur von %#v genutzt. Selten implementiert, aber nützlich für Bug-Reports und Code-Generation.
  • fmt.Formatter — die volle Kontrolle: Format(f State, verb rune). Erlaubt verb-spezifische Formatierung, etwa unterschiedliche Repräsentation für %v vs. %s vs. %q. Implementiert von time.Time, big.Int und ähnlichen Typen.

Die meisten Anwendungen brauchen nur Stringer. Formatter wird interessant, wenn ein Typ mehrere natürliche Darstellungen hat — eine kompakte für Logs, eine ausführliche für Debug-Output.

Funktionen — Print-Familie (zu Stdout)

Die Print-Familie schreibt direkt nach os.Stdout. Sie ist die Standardwahl für CLI-Output und schnelles Debugging.

  • fmt.Print — positional, kein Newline. Argumente werden mit Leerzeichen getrennt, wenn keines davon ein String ist.
  • fmt.Println — positional, Newline am Ende. Argumente immer mit Leerzeichen getrennt.
  • fmt.Printf — Format-String mit Verben, kein Newline. Die wichtigste Funktion des ganzen Pakets.

Funktionen — Fprint-Familie (zu io.Writer)

Die Fprint-Familie schreibt auf einen beliebigen io.Writer — eine Datei, ein Netzwerk-Socket, ein bytes.Buffer, os.Stderr. Identisches Verhalten wie Print, nur das Ziel ist explizit.

  • fmt.Fprint — positional, kein Newline.
  • fmt.Fprintln — positional, Newline am Ende.
  • fmt.Fprintf — Format-String, kein Newline. Standardwahl für strukturiertes Schreiben in Logs und HTTP-Responses.

Funktionen — Sprint-Familie (zu String)

Die Sprint-Familie liefert das Ergebnis als string zurück, ohne irgendwohin zu schreiben. Praktisch für String-Konstruktion, Logging-Pipelines und alles, was den Wert weiterverarbeitet.

  • fmt.Sprint — positional, kein Newline, liefert string.
  • fmt.Sprintln — positional, Newline am Ende, liefert string.
  • fmt.Sprintf — Format-String, liefert string. Die meistgenutzte Funktion des Pakets neben Printf.

Funktionen — Append-Familie (Go 1.19+)

Die Append-Familie schreibt formatierte Daten in einen vorhandenen []byte-Slice. Praktisch für Hot-Paths, in denen man Allokationen vermeiden möchte — der Slice wird wiederverwendet, kein neuer String entsteht.

Funktion — Error-Wrapping

  • fmt.Errorf — Format-String, liefert error. Mit dem %w-Verb der idiomatische Weg, Errors zu wrappen.

Funktionen — Scan-Familie

Die Scan-Familie parst Eingaben statt zu schreiben. In der Praxis selten genutzt — für ernsthaftes Parsing ist bufio.Scanner plus strconv deutlich robuster, weil Scan-Funktionen empfindlich auf Whitespace und Encoding reagieren. Trotzdem nützlich für simple Format-Konvertierungen.

Konzepte und Referenz

Diese Seiten erklären Querschnittsthemen, die mehrere Funktionen gleichzeitig betreffen.

Typen und Interfaces

  • fmt.StringerString() string. Das mit Abstand wichtigste Interface des Pakets.
  • fmt.GoStringerGoString() string für %#v.
  • fmt.FormatterFormat(f State, verb rune). Volle Kontrolle pro Verb.
  • fmt.Scanner — eigene Parse-Logik für die Scan-Familie. Spiegel zu Formatter.
  • fmt.ScanState — der Eingabe-Kontext für Scanner.Scan mit Token, SkipSpace, Width.
  • fmt.State — der Kontext, den Formatter.Format zur Laufzeit bekommt: Breite, Präzision, Flags, Writer.

Weiterführende Ressourcen

Externe Quellen