In che modo Go migliora la produttività con interfacce "implicite" e come si confronta con la nozione di metodi di estensione di C #?


21

Nel Go Language Tutorial, spiegano come funzionano le interfacce:

Go non ha classi. Tuttavia, è possibile definire metodi su tipi di struttura. Il destinatario del metodo appare nel proprio elenco di argomenti tra la parola chiave func e il nome del metodo.

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

Un tipo di interfaccia è definito da una serie di metodi. Un valore di tipo di interfaccia può contenere qualsiasi valore che implementa tali metodi.

Questo è l'unico modo per creare un'interfaccia in Go. Google spiega inoltre che:

Un tipo implementa un'interfaccia implementando i metodi. Non esiste una dichiarazione esplicita di intenti [ad esempio interfacedichiarazioni].

Le interfacce implicite separano i pacchetti di implementazione dai pacchetti che definiscono le interfacce: nessuno dei due dipende dall'altro.

Incoraggia anche la definizione di interfacce precise, perché non è necessario trovare tutte le implementazioni e contrassegnarle con il nome della nuova interfaccia.

Tutto ciò suona sospettosamente come metodi di estensione in C # , tranne per il fatto che i metodi in Go sono spietatamente polimorfici; opereranno su qualsiasi tipo che li implementa.

Google afferma che ciò incoraggia un rapido sviluppo, ma perché? Rinunci a qualcosa allontanandoti da interfacce esplicite in C #? I metodi di estensione in C # potrebbero consentire di trarre alcuni dei vantaggi che le interfacce Go hanno in C #?



1
Queste interfacce Go sembrano più simili a quelle che i modelli C ++ possono fare che ai metodi di estensione C #. In C # non c'è niente come "qualsiasi tipo che implementa i metodi A e B", ma puoi farlo usando i modelli C ++.
svick


Le "interfacce implicite" non sono solo una forma di dattilografia?
Allon Guralnek,

"Le" interfacce implicite "non sono solo una forma di battitura a papera?" Le interfacce di Go sono un esempio di tipizzazione strutturale. Concetto molto simile.
mortdeus,

Risposte:


12

Non vedo affatto i metodi di estensione e le interfacce implicite uguali.

Per prima cosa parliamo allo scopo.

I metodi di estensione esistono come uno zucchero sintattico specifico per darti la possibilità di usare un metodo come se fosse un membro di un oggetto, senza avere accesso agli interni di quell'oggetto. Senza i metodi di estensione puoi fare esattamente la stessa cosa, semplicemente non ottieni la piacevole sintassi di someObjectYouCantChange.YourMethod()e piuttosto devi chiamare YourMethod(someObjectYouCantChange).

Lo scopo delle interfacce implicite è tuttavia quello di poter implementare un'interfaccia su un oggetto a cui non si ha accesso al cambiamento. Questo ti dà la possibilità di creare una relazione polimorfica tra qualsiasi oggetto che scrivi e qualsiasi oggetto di cui non hai accesso agli interni.

Ora parliamo delle conseguenze.

I metodi di estensione non ne hanno davvero nessuno, questo è perfettamente in linea con gli spietati vincoli di sicurezza che .NET tenta di utilizzare per aiutare in distinte prospettive su un modello (la prospettiva dall'interno, dall'esterno, dall'erede e dal vicino). La conseguenza è solo una piacevolezza sintattica.

Le conseguenze delle interfacce implicite sono alcune cose.

  • Implementazione accidentale dell'interfaccia, questo può essere un incidente felice o una violazione accidentale di LSP incontrando l'interfaccia di qualcun altro che non avevi intenzione di non onorare l'intenzione del suo contratto.
  • La capacità di fare in modo che qualsiasi metodo accetti una beffa di un dato oggetto semplicemente rispecchiando l'interfaccia di quegli oggetti (o anche semplicemente creando un'interfaccia che soddisfi i requisiti di tali metodi e non di più).
  • La capacità di creare adattatori o altri vari schemi simili con maggiore facilità per quanto riguarda gli oggetti di cui non si può intromettersi.
  • Ritarda l'implementazione dell'interfaccia e implementala in un secondo momento senza dover toccare l'implementazione effettiva, implementandola solo quando desideri effettivamente creare un altro implementatore.

L'utilità dei metodi di estensione in Linq deriva in gran parte dalla loro capacità di innestare un'implementazione del metodo su un'interfaccia, in particolare IEnumerablee IQueryable. Mentre potresti fingere questo con staticmetodi in una classe di utilità, sarebbe goffo.
Robert Harvey,

@RobertHarvey Non è necessariamente corretto affermare che inserisce il metodo su un'interfaccia, notare la differenza tra un metodo effettivo su un'interfaccia e un metodo di estensione: un metodo su un'interfaccia verrà implementato all'interno della classe che implementa tale interfaccia, e quindi ha accesso a molto più di qualsiasi altro metodo di estensione. Ancora una volta è un cambiamento di prospettiva, al codice implementato all'interno di una classe viene data una prospettiva speciale rispetto a quella esterna.
Jimmy Hoffa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.