Comment Go améliore-t-il la productivité avec des interfaces «implicites», et comment cela se compare-t-il avec la notion de C # de méthodes d'extension?

21

Dans le didacticiel Go Language, ils expliquent le fonctionnement des interfaces:

Go n'a pas de cours. Cependant, vous pouvez définir des méthodes sur les types de structure. Le récepteur de méthode apparaît dans sa propre liste d'arguments entre le mot-clé func et le nom de la méthode.

type Vertex struct {
    X, Y float64
}

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

Un type d'interface est défini par un ensemble de méthodes. Une valeur de type interface peut contenir n'importe quelle valeur qui implémente ces méthodes.

C'est le seul moyen de créer une interface dans Go. Google explique en outre que:

Un type implémente une interface en implémentant les méthodes. Il n'y a pas de déclaration d'intention explicite [c'est-à-dire des interfacedéclarations].

Les interfaces implicites découplent les packages d'implémentation des packages qui définissent les interfaces: aucun ne dépend de l'autre.

Il encourage également la définition d'interfaces précises, car vous n'avez pas besoin de trouver chaque implémentation et de la marquer avec le nouveau nom d'interface.

Tout cela ressemble étrangement à des méthodes d'extension en C # , sauf que les méthodes de Go sont impitoyablement polymorphes; ils fonctionneront sur tout type qui les met en œuvre.

Google affirme que cela encourage un développement rapide, mais pourquoi? Abandonnez-vous quelque chose en vous éloignant des interfaces explicites en C #? Les méthodes d'extension en C # pourraient-elles permettre de tirer certains des avantages des interfaces Go en C #?

Robert Harvey
la source
Robert Harvey
1
Ces interfaces Go ressemblent plus à ce que les modèles C ++ peuvent faire qu'aux méthodes d'extension C #. En C #, rien de tel que «n'importe quel type qui implémente les méthodes A et B», mais vous pouvez le faire en utilisant des modèles C ++.
svick
Connexes: codeproject.com/Articles/9281/…
Robert Harvey
Les «interfaces implicites» ne sont-elles pas simplement une forme de typage de canard?
Allon Guralnek
"Les" interfaces implicites "ne sont-elles pas simplement une forme de frappe de canard?" Les interfaces de Go sont un exemple de typage structurel. Concept très similaire.
mortdeus

Réponses:

12

Je ne vois pas du tout les méthodes d'extension et les interfaces implicites.

Parlons d'abord du but.

Les méthodes d'extension existent en tant que sucre syntaxique spécifiquement pour vous donner la possibilité d'utiliser une méthode comme si elle était membre d'un objet, sans avoir accès aux éléments internes de cet objet. Sans méthodes d'extension, vous pouvez faire exactement la même chose, vous n'avez tout simplement pas la syntaxe agréable de someObjectYouCantChange.YourMethod()et devez plutôt appeler YourMethod(someObjectYouCantChange).

Le but des interfaces implicites est cependant de vous permettre d'implémenter une interface sur un objet auquel vous n'avez pas accès pour changer. Cela vous donne la possibilité de créer une relation polymorphe entre tout objet que vous écrivez vous-même et tout objet dont vous n'avez pas accès aux éléments internes.

Parlons maintenant des conséquences.

Les méthodes d'extension n'en ont vraiment aucune, cela correspond parfaitement aux contraintes de sécurité impitoyables que NET essaie d'utiliser pour aider à des perspectives distinctes sur un modèle (la perspective de l'intérieur, de l'extérieur, de l'héritier et du voisin). La conséquence est juste une certaine plaisance syntaxique.

Les conséquences des interfaces implicites sont quelques choses.

  • Implémentation accidentelle de l'interface, cela peut être un heureux accident ou une violation accidentelle du LSP en rencontrant l'interface de quelqu'un d'autre que vous n'aviez pas l'intention de respecter sans respecter l'intention de son contrat.
  • La possibilité de faire facilement n'importe quelle méthode accepter une maquette d'un objet donné du tout en reflétant simplement l'interface de ces objets (ou même simplement en créant une interface qui répond aux exigences de cette méthode et pas plus).
  • La possibilité de créer des adaptateurs ou d'autres modèles similaires avec plus de facilité en ce qui concerne les objets dont vous ne pouvez pas vous mêler.
  • Retardez l'implémentation de l'interface et implémentez-la ultérieurement sans avoir à toucher à l'implémentation réelle, l'implémentant uniquement lorsque vous souhaitez réellement créer un autre implémenteur.
Jimmy Hoffa
la source
L'utilité des méthodes d'extension dans Linq découle en grande partie de leur capacité à greffer une implémentation de méthode sur une interface, en particulier IEnumerableet IQueryable. Bien que vous puissiez simuler cela avec des staticméthodes dans une classe utilitaire, ce serait maladroit.
Robert Harvey
@RobertHarvey Il n'est pas nécessairement exact de prétendre qu'il met la méthode sur une interface, notez la différence entre une méthode réelle sur une interface et une méthode d'extension: une méthode sur une interface sera implémentée à l'intérieur de la classe qui implémente cette interface, et donc a accès à bien plus que n'importe quelle méthode d'extension. Encore une fois, c'est un changement de perspective, le code implémenté à l'intérieur d'une classe reçoit une perspective spéciale par rapport à l'extérieur.
Jimmy Hoffa