ProgrammazioneSviluppatore Go Backend

Quali sono le interfacce in Go, come vengono implementate e confrontate, e in cosa si differenziano dalle interfacce in altri linguaggi?

Supera i colloqui con l'assistente IA Hintsage

Risposta

Le interfacce in Go sono un insieme di metodi che un tipo deve implementare per corrispondere a quell'interfaccia. Non esiste una parola chiave esplicita implements: la compatibilità è strutturale, non dichiarativa. L'assegnazione di un tipo implementante a una variabile di tipo interfaccia è possibile solo se il tipo implementa tutti i metodi dell'interfaccia.

Importante: la variabile interfaccia contiene due puntatori: ai dati (value) e al tipo (type).

Esempio di dichiarazione e implementazione:

type Printer interface { Print() } type MyPrinter struct{} func (mp MyPrinter) Print() { fmt.Println("printing...") } var p Printer = MyPrinter{} p.Print() // "printing..."

Domanda insidiosa

Cosa succede se la variabile interfaccia è uguale a nil? In cosa differisce "var i interface{} = nil" da "var i interface{}"?

Risposta errata frequente — "entrambi i valori sono nil". In realtà — no:

  • var i interface{} = nil — la variabile è effettivamente nil (type=nil, value=nil)
  • Ma se var p *MyPrinter = nil; var i Printer = p, allora i != nil, perché type != nil (all'interno di i — type=*MyPrinter, value=nil), e molte verifiche come if i == nil non funzioneranno quando ci si aspetta.

Esempio:

var p *MyPrinter = nil var i Printer = p fmt.Println(i == nil) // false!

Esempi di errori reali a causa della mancanza di conoscenza delle sottigliezze del tema


Storia

Descrizione: In un servizio, il gestore degli errori restituiva un'interfaccia con valore nil, e i clienti pensavano che l'errore fosse non nullo, causando azioni superflue. Il problema era nel confronto dell'interfaccia con nil.


Storia

Descrizione: Durante la scrittura dei test, si controllava erroneamente l'errore di tipo interfaccia su uguaglianza a nil dopo il ritorno di una struttura con campi nil. I test non rilevavano errori reali, portando a un bug in produzione.


Storia

Descrizione: Durante la migrazione da un tipo interfaccia a un altro, si dimenticò di implementare tutti i metodi della nuova interfaccia, poiché non c'era un esplicito implements. Il codice compilava, ma l'interfaccia non veniva implementata, alcune funzioni mock avevano smesso di funzionare.