Penso che la risposta a questa domanda ha bisogno di un approccio più retrospettivo verso la grammatica, e come sarebbe la sua attuazione attraverso l'ingegneria del software. (scusi la semplificazione sopra)
Prima un rapido flashback di ciò che sono types
?
Sono solo blocchi di memoria con la logica del compilatore in cima. Ciò che rende uno array
diverso da un string
è ciò che il compilatore ci consente di fare con quei blocchi di memoria. (Si pensi più profondo e si può cominciare a realizzare la vera differenza tra strongly typed
e dynamically typed
lingue.)
Ora successiva è necessario rendersi conto che i puntatori sono i loro propri tipi per dire.
*variable
è un diverso blocco di memoria (di tipo noto) rispetto a variable
. È solo che il compilatore presume sempre che il contenuto di *variable
sarà sempre un indirizzo di un blocco di memoria di tipo a destra della dichiarazione insieme ad altre restrizioni/funzionalità che impone.
Quindi ricapitoliamo cos'è un'interfaccia.
Definizione pseudo-scientifica: un insieme di requisiti per qualsiasi cittadino di prima classe di un tipo specifico. Tradotto software Engineering- qualsiasi blocco di memoria (tipi) che ha la stessa struttura di memoria (ripercorrere structure packing) associato ad esso, come descritto in un contratto (interface
) può essere passato intorno come con il nome tipo che il contratto menziona.
Ora si può cominciare a rendersi conto che quando si dice
func (f *Faz) Bar() string
è 'blocco di s di memoria che una funzione, dove f
' f
s tipo è un puntatore a Faz
dove aree
func (f Faz) Bar() string
è il blocco di memoria f
, dove il tipo di f
è Faz
Così, quando si sta dicendo che una variabile di tipo *Faz
è soddisfacente un contratto, allora come si può supporre che una variabile di tipo Faz
si qualificherà come tipo di interfaccia nel codice? Scegli chi soddisfa il tuo contratto e solo quel tipo può assumere il tipo di interfaccia nel tuo codice.
[Vedere questo post] (http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go). –
Come una nota a margine: l'articolo a cui fa riferimento @KerrekSB mi ha aiutato a capire che quando Go si lamenta "MyFoo non implementa Foo (il metodo Bar ha ricevitore puntatore)", ciò non significa che non si può usare un ricevitore puntatore. Significa che o _none_ dei metodi di 'MyFoo' che implementano' Bar' dovrebbe avere ricevitori di puntatori, o _all_ di essi deve. Questo è un problema diverso da @ 0xor1, ma altri potrebbero trovare questa domanda perché stanno mixando i loro tipi di ricevitore (come me) e non capendo l'errore che stanno ottenendo. – Hephaestus