Interfaccia fmt.Stringer
Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 75 di 107.
L’interfaccia fmt.Stringer controlla come appaiono i tuoi tipi quando vengono stampati. È una delle interfacce implementate più comunemente in Go, definita nel pacchetto fmt:
type Stringer interface {
String() string
}Quando passi un valore a fmt.Println, a fmt.Printf con %v o a funzioni simili, Go verifica se il tipo implementa Stringer. Se sì, Go chiama il metodo String() per ottenere la rappresentazione testuale.
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
}Senza il metodo String(), la stampa mostrerebbe il formato predefinito della struct: {23.5}. Implementando Stringer, controlli esattamente come viene presentato il tuo tipo.
Questo è particolarmente utile per i tipi i cui valori grezzi dei campi non comunicano chiaramente il loro significato. Un tipo Duration potrebbe essere visualizzato come "2h 30m" invece di mostrare i nanosecondi grezzi, oppure un tipo User potrebbe mostrare un nome formattato invece di tutti i suoi campi.
Sfida
FacileCostruiamo un sistema di monitoraggio del tempo che mostra le durate in un formato intuitivo! Implementerai l'interfaccia fmt.Stringer per controllare come vengono visualizzati i tuoi tipi personalizzati quando vengono stampati.
Organizzerai il codice in due file:
duration.go: definisci i tuoi tipi relativi al tempo con rappresentazioni testuali personalizzate.Crea una struct
Durationche memorizza il numero totale di minuti come intero. Implementa il metodoString()in modo che, quando viene stampato, mostri una rappresentazione leggibile come2h 30mper 150 minuti o0h 45mper 45 minuti. Ore e minuti devono essere mostrati sempre.Crea una struct
Taskcon i campiName(stringa) eTime(Duration). ImplementaString()su Task per visualizzarlo nel formato[Name]: [duration], dove la durata usa il proprio metodo String.main.go: crea e visualizza attività con le relative durate.Leggi il numero di attività, poi leggi il nome e la durata in minuti di ciascuna attività. Crea istanze di Task e stampa direttamente ciascuna usando
fmt.Println: l'interfaccia Stringer gestirà automaticamente la formattazione.Dopo aver stampato tutte le attività, calcola e stampa il tempo totale di tutte le attività nel formato:
Total: [duration]
Verranno forniti i seguenti input:
- Riga 1: numero di attività
- Righe successive: nome dell'attività e minuti (due righe per attività)
Ad esempio, dato:
3
Code Review
90
Meeting
45
Documentation
120L'output dovrebbe essere:
Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15mE dato:
2
Design
180
Testing
65L'output dovrebbe essere:
Design: 3h 0m
Testing: 1h 5m
Total: 4h 5mImplementando Stringer, i tuoi tipi si integrano perfettamente con le funzioni di stampa di Go. Invece di vedere i campi grezzi della struct, come {90}, ottieni un output significativo e comprensibile per gli utenti.
Provalo tu
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Leggi il numero di attività
line, _ := reader.ReadString('\n')
numTasks, _ := strconv.Atoi(strings.TrimSpace(line))
// TODO: Crea uno slice per memorizzare le attività
// TODO: Tieni traccia del totale dei minuti
for i := 0; i < numTasks; i++ {
// Leggi il nome dell'attività
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Leggi la durata dell'attività in minuti
minutesLine, _ := reader.ReadString('\n')
minutes, _ := strconv.Atoi(strings.TrimSpace(minutesLine))
// TODO: Crea un Task con il nome e Duration
// TODO: Stampa l'attività (fmt.Println userà l'interfaccia Stringer)
// TODO: Aggiungi i minuti al totale
_ = name
_ = minutes
}
// TODO: Stampa la durata totale nel formato "Total: Xh Ym"
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti di OOP in Go
File esterniWorkspace e moduli GoPacchetti e importazioniNomi esportati e non esportatiIntroduzione all’OOP in GoGli struct come classiDefinire metodi sugli structReceiver con puntatore vs receiver con valoreInizializzazione degli structFunzioni costruttriciRiepilogo - Calcolatrice semplice4Interfacce
Introduzione alle interfacceImplementazione implicitaL’interfaccia come contrattoInterfaccia vuota (any)Asserzione di tipoSwitch sul tipoComposizione di interfacceInterfacce Stringer ed ErrorRipasso - Calcolatore di forme7Incapsulamento
Campi esportati e non esportatiIncapsulamento a livello di packageMetodi Getter e SetterNascondimento delle informazioni in GoRiepilogo - Registri degli studenti10Tipi generici (Go 1.18+)
Introduzione ai tipi genericiParametri di tipoVincoli di tipoStruct genericheSoluzione alternativa per i metodi genericiRiepilogo - Collezione generica13Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneModello SingletonModello FactoryModello Abstract FactoryModello ObserverModello Strategy2Approfondimento su tipi e struct
Tipi di base e compostiDefinizioni di tipi personalizzatiTag delle structStruct anonimeStruct annidateValori zero e predefinitiRipasso - Rubrica5Composizione invece dell'ereditarietà
Perché Go non ha l'ereditarietàFondamenti dell'embedding delle structPromozione dei metodiEmbedding di più structEmbedding e aggregazione a confrontoMascheramento dei metodi embeddedRiepilogo: gerarchia dei dipendenti8Gestione degli errori e OOP
L'interfaccia errorTipi di errore personalizzatiWrapping degli errori (fmt.Errorf)Errori sentinellaerrors.Is() ed errors.As()Panic, Defer e RecoverRiepilogo - Parser di file11Libreria standard e OOP
io.Reader e io.Writersort.InterfaceInterfaccia fmt.Stringerencoding/json con le structInterfaccia http.HandlerRipasso - modelli REST API14Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeMiddleware come Decorator3Puntatori e memoria
Concetti base dei puntatori in GoPuntatori a structPassaggio per valore vs per riferimentoLa funzione new()Garbage collection in GoRiepilogo - Costruttore di liste concatenate6Polimorfismo in Go
Polimorfismo tramite interfacceDuck typing in GoRegole di soddisfacimento delle interfacceCollezioni polimorficheIniezione delle dipendenzeRiepilogo - Elaboratore di pagamenti9Concorrenza e OOP
Basi delle goroutineCanali e comunicazioneCanali bufferizzati vs non bufferizzatiIstruzione selectsync.Mutex e sync.RWMutexsync.WaitGroupProgettazione di struct thread-safeRiepilogo: worker poolEsercitati da solo: Compilatore Go online