fmt.Stringer-Interface
Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 75 von 107.
Die fmt.Stringer-Schnittstelle bestimmt, wie deine Typen bei der Ausgabe erscheinen. Sie ist eine der am häufigsten implementierten Schnittstellen in Go und im fmt-Paket definiert:
type Stringer interface {
String() string
}Wenn du einen Wert an fmt.Println, fmt.Printf mit %v oder ähnliche Funktionen übergibst, prüft Go, ob der Typ Stringer implementiert. Wenn dies der Fall ist, ruft Go die String()-Methode auf, um die Textdarstellung zu erhalten.
type Temperature struct {
Celsius float64
}
func (t Temperature) String() string {
return fmt.Sprintf("%.1f°C", t.Celsius)
}
func main() {
temp := Temperature{Celsius: 23.5}
fmt.Println(temp) // 23.5°C
}Ohne die Methode String() würde die Ausgabe das standardmäßige Struct-Format anzeigen: {23.5}. Durch die Implementierung von Stringer legst du genau fest, wie dein Typ dargestellt wird.
Dies ist besonders nützlich für Typen, bei denen die rohen Feldwerte die Bedeutung nicht eindeutig vermitteln. Ein Typ Duration könnte als „2h 30m“ angezeigt werden, anstatt rohe Nanosekunden anzuzeigen, oder ein Typ User könnte einen formatierten Namen anstelle all seiner Felder anzeigen.
Aufgabe
EinfachErstellen wir ein Zeiterfassungssystem, das Zeitdauern in einem für Menschen verständlichen Format anzeigt! Du implementierst die fmt.Stringer-Schnittstelle, um zu steuern, wie deine benutzerdefinierten Typen bei der Ausgabe erscheinen.
Du organisierst deinen Code auf zwei Dateien:
duration.go: Definiere deine zeitbezogenen Typen mit benutzerdefinierten Zeichenkettenrepräsentationen.Erstelle eine
Duration-Struktur, die eine Gesamtanzahl von Minuten als Ganzzahl speichert. Implementiere die MethodeString(), sodass sie bei der Ausgabe ein lesbares Format wie2h 30mfür 150 Minuten oder0h 45mfür 45 Minuten anzeigt. Stunden und Minuten sollen immer angezeigt werden.Erstelle eine
Task-Struktur mit den FeldernName(Zeichenkette) undTime(Duration). ImplementiereString()für Task, sodass die Ausgabe im Format[Name]: [duration]erfolgt, wobei die Dauer ihre eigene String-Methode verwendet.main.go: Erstelle Aufgaben und zeige sie mit ihren Zeitdauern an.Lies die Anzahl der Aufgaben ein und lies anschließend für jede Aufgabe ihren Namen und ihre Dauer in Minuten ein. Erstelle Task-Instanzen und gib jede direkt mit
fmt.Printlnaus: Die Stringer-Schnittstelle übernimmt die Formatierung automatisch.Nachdem alle Aufgaben ausgegeben wurden, berechne die Gesamtzeit aller Aufgaben und gib sie im folgenden Format aus:
Total: [duration]
Die folgenden Eingaben werden bereitgestellt:
- Zeile 1: Anzahl der Aufgaben
- Folgende Zeilen: Aufgabenname und Minuten (zwei Zeilen pro Aufgabe)
Zum Beispiel bei folgender Eingabe:
3
Code Review
90
Meeting
45
Documentation
120Deine Ausgabe sollte wie folgt aussehen:
Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15mUnd bei folgender Eingabe:
2
Design
180
Testing
65Deine Ausgabe sollte wie folgt aussehen:
Design: 3h 0m
Testing: 1h 5m
Total: 4h 5mDurch die Implementierung von Stringer lassen sich deine Typen nahtlos in die Ausgabefunktionen von Go integrieren. Anstatt rohe Strukturfelder wie {90} zu sehen, erhältst du eine aussagekräftige Ausgabe, die für Benutzer verständlich ist.
Probier es selbst
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Lies die Anzahl der Tasks
line, _ := reader.ReadString('\n')
numTasks, _ := strconv.Atoi(strings.TrimSpace(line))
// TODO: Erstelle ein Slice zum Speichern der Tasks
// TODO: Verfolge die Gesamtminuten
for i := 0; i < numTasks; i++ {
// Lies den Task-Namen
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Lies die Task-Dauer in Minuten
minutesLine, _ := reader.ReadString('\n')
minutes, _ := strconv.Atoi(strings.TrimSpace(minutesLine))
// TODO: Erstelle einen Task mit dem Namen und Duration
// TODO: Gib den Task aus (fmt.Println verwendet das Stringer-Interface)
// TODO: Addiere minutes zum total
_ = name
_ = minutes
}
// TODO: Gib die Gesamtdauer im Format "Total: Xh Ym" aus
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP in Go
Externe DateienGo-Workspace & ModulePackages & ImportsExportierte vs. nicht exportierte NamenEinführung in OOP mit GoStructs als KlassenMethoden für Structs definierenPointer- vs. Value-ReceiverStruct-InitialisierungKonstruktorfunktionenRückblick – Einfacher Taschenrechner4Schnittstellen
Einführung in SchnittstellenImplizite ImplementierungSchnittstelle als VertragLeere Schnittstelle (any)TypzusicherungTypwechselZusammensetzung von SchnittstellenStringer- und Error-SchnittstellenRückblick – Formenrechner7Kapselung
Exportierte vs. nicht exportierte FelderKapselung auf PaketebeneGetter- und Setter-MethodenInformationsverbergung in GoRückblick – Studierendendatensätze10Generics (Go 1.18+)
Einführung in GenericsTypparameterTypbeschränkungenGenerische StrukturenWorkaround für generische MethodenZusammenfassung – Generische Sammlung2Typen & Structs im Detail
Grundlegende & zusammengesetzte TypenBenutzerdefinierte TypdefinitionenStruct-TagsAnonyme StructsVerschachtelte StructsNullwerte & StandardwerteRückblick – Kontaktbuch5Komposition statt Vererbung
Warum Go keine Vererbung hatGrundlagen der Struct-EinbettungMethoden-PromotionMehrere Structs einbettenEinbettung vs. AggregationVerbergen eingebetteter MethodenRückblick – Mitarbeiterhierarchie8Fehlerbehandlung & OOP
Das Error-InterfaceBenutzerdefinierte FehlertypenError-Wrapping (fmt.Errorf)Sentinel-Fehlererrors.Is() und errors.As()Panic, Defer und RecoverRückblick – Dateiparser11Standardbibliothek & OOP
io.Reader & io.Writersort.Interfacefmt.Stringer-Interfaceencoding/json mit Structshttp.Handler-InterfaceRückblick – REST-API-Modelle3Zeiger & Speicher
Grundlagen von Zeigern in GoZeiger auf StructsÜbergabe per Wert vs. ReferenzDie Funktion new()Garbage Collection in GoRückblick – Verkettete Liste erstellen6Polymorphismus in Go
Polymorphismus über InterfacesDuck-Typing in GoRegeln zur Interface-ErfüllungPolymorphe SammlungenDependency InjectionZusammenfassung – Zahlungsprozessor9Konkurrenz & OOP
Grundlagen der GoroutinesChannels & KommunikationGepufferte vs. ungepufferte ChannelsSelect-Anweisungsync.Mutex & sync.RWMutexsync.WaitGroupThread-sicheres Struct-DesignRückblick – Worker PoolÜbe selbstständig: Online-Go-Compiler