Se la logica di stampa dipende dall'interfaccia ma non sulle struct stessi, allora è meglio spostare stampa a una funzione libera che opera su un'interfaccia.
Nel tuo caso, il metodo PrintStr
viene utilizzato per stampare una stringa che è un membro di ogni struttura.
In questo caso, significa che ogni struttura deve implementare un'interfaccia che restituisce la stringa necessaria utilizzata per la stampa e PrintStr
diventa una funzione che utilizza un parametro Printable
.
type First struct {
str string
}
type Second struct {
str string
}
type Printable interface {
String() string
}
func (p First) String() string {
return p.str
}
func (p Second) String() string {
return p.str
}
func PrintStr(p Printable) {
fmt.Print(p.String())
}
L'utilizzo dell'interfaccia A
è non-idiomatica perché un interfaccia non dovrebbe dipendere dalla realizzazione della sua funzionalità.
Invece, con questa soluzione, è possibile mantenere l'interfaccia A, ma semplificare ogni implementazione:
func (f First) PrintStr() {
PrintStr(f)
}
func (s Second) PrintStr() {
PrintStr(s)
}
È ancora ridondante, ma la logica risiede nella funzione chiamata da lì, limitando la è necessario eseguire il copia-incolla in caso di modifica della logica di stampa.
Questo modello è comune nella libreria standard Go, poiché molte funzioni utili sono costruite su interfacce che non possono estendere, ad esempio io.Reader.
Si tratta di una semplice interfaccia con un solo metodo, ma viene utilizzata completamente da molti altri pacchetti.
Se si osserva la funzione ioutil.ReadAll, si potrebbe sostenere che avrebbe potuto essere implementato come un altro metodo dell'interfaccia io.Reader
, tuttavia questo semplifica i lettori, concentrandosi sul loro singolo metodo, consentendo a qualsiasi implementatore di utilizzare ReadAll gratuitamente.
Sembra anche un po 'ridondante avere 2 strutture con gli stessi tipi. – TheHippo
Sì, ma questo è un esempio di giocattolo. Primo e Secondo potrebbero condividere alcuni campi e non altri. Il punto è che voglio che una funzione si comporti esattamente nello stesso modo per due tipi diversi, senza dover ripetere il codice. – Ekaterina