¿Cómo mejora Go la productividad con interfaces "implícitas" y cómo se compara eso con la noción de métodos de extensión de C #?

21

En Go Language Tutorial, explican cómo funcionan las interfaces:

Ir no tiene clases. Sin embargo, puede definir métodos en tipos de estructura. El receptor del método aparece en su propia lista de argumentos entre la palabra clave func y el nombre del método.

type Vertex struct {
    X, Y float64
}

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

Un tipo de interfaz se define mediante un conjunto de métodos. Un valor de tipo de interfaz puede contener cualquier valor que implemente esos métodos.

Esta es la única forma de crear una interfaz en Go. Google explica además que:

Un tipo implementa una interfaz mediante la implementación de los métodos. No existe una declaración explícita de intenciones [es decir, interfacedeclaraciones].

Las interfaces implícitas desacoplan los paquetes de implementación de los paquetes que definen las interfaces: ninguno depende del otro.

También fomenta la definición de interfaces precisas, ya que no tiene que encontrar todas las implementaciones y etiquetarlas con el nuevo nombre de interfaz.

Todo esto suena sospechosamente como métodos de extensión en C # , excepto que los métodos en Go son implacablemente polimórficos; operarán en cualquier tipo que los implemente.

Google afirma que esto fomenta el desarrollo rápido, pero ¿por qué? ¿Renuncias a algo alejándote de las interfaces explícitas en C #? ¿Podrían los métodos de extensión en C # permitirle obtener algunos de los beneficios que tienen las interfaces Go en C #?

Robert Harvey
fuente
Relacionado: stackoverflow.com/q/11441905
Robert Harvey
1
Estas interfaces Go se parecen más a lo que pueden hacer las plantillas de C ++ que a los métodos de extensión de C #. En C # no hay nada como "cualquier tipo que implemente los métodos A y B", pero puede hacerlo usando plantillas de C ++.
svick
Relacionado: codeproject.com/Articles/9281/…
Robert Harvey
¿No son las 'interfaces implícitas' solo una forma de escribir pato?
Allon Guralnek
"¿No son las 'interfaces implícitas' solo una forma de escribir pato?" Las interfaces de Go son un ejemplo de tipificación estructural. Concepto muy similar
mortdeus

Respuestas:

12

No veo los métodos de extensión y las interfaces implícitas como iguales en absoluto.

Primero hablemos con un propósito.

Los métodos de extensión existen como un azúcar sintáctico específicamente para darle la capacidad de usar un método como si fuera un miembro de un objeto, sin tener acceso a las partes internas de ese objeto. Sin métodos de extensión puede hacer exactamente lo mismo, simplemente no obtiene la sintaxis agradable someObjectYouCantChange.YourMethod()y más bien tiene que llamar YourMethod(someObjectYouCantChange).

Sin embargo, el propósito de las interfaces implícitas es que pueda implementar una interfaz en un objeto que no tiene acceso para cambiar. Esto le brinda la capacidad de crear una relación polimórfica entre cualquier objeto que escriba usted mismo y cualquier objeto del que no tenga acceso a las partes internas.

Ahora hablemos de las consecuencias.

Los métodos de extensión realmente no tienen ninguno, esto está perfectamente en línea con las despiadadas restricciones de seguridad que .NET intenta usar para ayudar en distintas perspectivas en un modelo (la perspectiva desde adentro, afuera, heredero y vecino). La consecuencia es solo algo de placer sintáctico.

Las consecuencias de las interfaces implícitas son algunas cosas.

  • Implementación accidental de la interfaz, esto puede ser un accidente feliz o una violación accidental del LSP al conocer la interfaz de otra persona que no tenía la intención de no cumplir con la intención de su contrato.
  • La capacidad de hacer que cualquier método acepte fácilmente una imitación de cualquier objeto dado simplemente reflejando esa interfaz de objetos (o incluso simplemente creando una interfaz que cumpla con los requisitos de los métodos y nada más).
  • La capacidad de crear adaptadores u otros patrones similares con más facilidad con respecto a los objetos que no puede entrometerse en las entrañas.
  • Retrasar la implementación de la interfaz e implementarla más tarde sin tener que tocar la implementación real, solo implementando cuando realmente desea crear otro implementador.
Jimmy Hoffa
fuente
La utilidad de los métodos de extensión en Linq deriva en gran parte de su capacidad para injertar una implementación de método en una interfaz, en particular IEnumerabley IQueryable. Si bien podría fingir esto con staticmétodos en una clase de utilidad, sería torpe.
Robert Harvey
@RobertHarvey No es necesariamente exacto afirmar que coloca el método en una interfaz, tenga en cuenta la diferencia entre un método real en una interfaz y un método de extensión: un método en una interfaz se implementará dentro de la clase que implementa esa interfaz, y por lo tanto tiene acceso disponible a mucho más que cualquier método de extensión. Nuevamente es un cambio de perspectiva, el código implementado dentro de una clase tiene una perspectiva especial en comparación con el exterior.
Jimmy Hoffa