Como o Go melhora a produtividade com interfaces "implícitas" e como isso se compara à noção de métodos de extensão do C #?


21

No Go Language Tutorial, eles explicam como as interfaces funcionam:

Go não tem aulas. No entanto, você pode definir métodos nos tipos de estrutura. O receptor do método aparece em sua própria lista de argumentos entre a palavra-chave func e o nome do método.

type Vertex struct {
    X, Y float64
}

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

Um tipo de interface é definido por um conjunto de métodos. Um valor do tipo de interface pode conter qualquer valor que implemente esses métodos.

Essa é a única maneira de criar uma interface no Go. O Google explica ainda que:

Um tipo implementa uma interface implementando os métodos. Não há declaração explícita de intenção [ie interfacedeclarações].

As interfaces implícitas separam os pacotes de implementação dos pacotes que definem as interfaces: nenhum depende do outro.

Também incentiva a definição de interfaces precisas, porque você não precisa encontrar todas as implementações e identificá-las com o novo nome da interface.

Tudo isso parece suspeito como Métodos de extensão em C # , exceto que os métodos em Go são implacavelmente polimórficos; eles irão operar em qualquer tipo que os implemente.

O Google alega que isso incentiva o desenvolvimento rápido, mas por quê? Você desiste de algo afastando-se de interfaces explícitas em C #? Os métodos de extensão em C # permitem derivar alguns dos benefícios que as interfaces Go têm em C #?



1
Essas interfaces Go parecem mais o que os modelos C ++ podem fazer do que os métodos de extensão C #. No C #, não há nada como "qualquer tipo que implemente os métodos A e B", mas você pode fazer isso usando modelos C ++.
Sv16 de


As 'interfaces implícitas' não são apenas uma forma de digitação de pato?
Allon Guralnek

"As 'interfaces implícitas' não são apenas uma forma de digitação de pato?" As interfaces da Go são um exemplo de tipagem estrutural. Conceito muito parecido
mortdeus

Respostas:


12

Não vejo métodos de extensão e interfaces implícitas iguais.

Primeiro vamos falar com um propósito.

Os métodos de extensão existem como um açúcar sintático especificamente para fornecer a capacidade de usar um método como se fosse um membro de um objeto, sem ter acesso às partes internas desse objeto. Sem métodos de extensão, você pode fazer exatamente a mesma coisa, simplesmente não obtém a sintaxe agradável someObjectYouCantChange.YourMethod()e precisa chamar YourMethod(someObjectYouCantChange).

O objetivo das interfaces implícitas, no entanto, é para que você possa implementar uma interface em um objeto que não tem acesso para alterar. Isso permite criar um relacionamento polimórfico entre qualquer objeto que você escreve e qualquer objeto do qual não tenha acesso aos elementos internos.

Agora vamos falar das consequências.

Os métodos de extensão realmente não têm nenhum, isso está perfeitamente alinhado com as implacáveis ​​restrições de segurança que o .NET tenta usar para ajudar em perspectivas distintas em um modelo (a perspectiva de dentro, de fora, de herdador e vizinha). A consequência é apenas um pouco de prazer sintático.

As consequências de interfaces implícitas são algumas coisas.

  • Implementação acidental da interface, pode ser um acidente feliz ou uma violação acidental do LSP, encontrando a interface de outra pessoa que você não pretendia sem respeitar a intenção do contrato.
  • A capacidade de fazer qualquer método facilmente aceitar uma farsa de qualquer objeto, simplesmente espelhando a interface desse objeto (ou mesmo criando uma interface que atenda aos requisitos desse método e não mais).
  • A capacidade de criar adaptadores ou outros vários padrões semelhantes com mais facilidade em relação aos objetos dos quais você não pode se intrometer.
  • Adie a implementação da interface e implemente-a posteriormente sem precisar tocar na implementação real, implementando-a somente quando você realmente desejar criar outro implementador.

A utilidade dos métodos de extensão no Linq deriva em grande parte por sua capacidade de enxertar uma implementação de método em uma interface, em particular IEnumerablee IQueryable. Embora você possa fingir isso com staticmétodos em uma classe de utilitário, seria desajeitado.
Robert Harvey

@RobertHarvey Não é necessariamente exato afirmar que ele coloca o método em uma interface; observe a diferença entre um método real em uma interface e um método de extensão: um método em uma interface será implementado dentro da classe que implementa essa interface e, portanto, tem acesso disponível a muito mais do que qualquer método de extensão. Novamente, é uma mudança de perspectiva; o código implementado dentro de uma classe recebe uma perspectiva especial em comparação com a externa.
Jimmy Hoffa
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.