Pular para o conteúdo
Tecnologia

Interfaces em Go: introdução prática

Desvende o funcionamento das interfaces em Go com explicações diretas, metáforas simples e exemplos práticos de código.

O que é uma interface em Go?

Em Go, uma interface define um conjunto de métodos que um tipo precisa implementar para
ser considerado compatível com ela. Diferente de linguagens como Java, essa
implementação é implícita: se um tipo possui os métodos pedidos, ele é automaticamente
aceito.

Atenção

Interfaces não conhecem implementações. Elas apenas exigem a presença de métodos
específicos — um verdadeiro contrato de comportamento.

Metáfora simples: o contrato do jogador

Pense em um jogador de futebol assinando com um clube. O contrato não exige saber a
posição do atleta, mas apenas que ele jogue conforme acordado. Interfaces seguem esse
mesmo conceito: o que importa é o que será feito, não como ou por quem.

Atenção

Ao usar interfaces, você foca nos comportamentos esperados e não na implementação
concreta. Isso reduz o acoplamento e permite mais flexibilidade no código.

Definindo comportamentos com interfaces

Suponha uma interface chamada Animal com um método FazerBarulho. Cachorros implementam
latido, gatos fazem miau — cada um à sua maneira. O programa apenas exige que eles façam
barulho, não importa como.

Interface implícita em Go

Em Go, basta um tipo implementar os métodos da interface para que ele seja compatível.
Isso simplifica o código e aumenta a flexibilidade; sempre que um tipo definir todos os
métodos esperados, ele passa a satisfazer a interface.

Polimorfismo em ação

Interfaces permitem tratar objetos diferentes de forma uniforme. Com uma interface Forma
que define o método Área, podemos utilizar tanto Círculo quanto Quadrado sem precisar se
preocupar com as diferenças internas de cálculo.

Info Extra

Isso é polimorfismo: múltiplos tipos com comportamentos distintos, tratados de maneira
uniforme.

Desacoplamento com interfaces

Interfaces estabelecem fronteiras claras entre partes do sistema. Arquiteturas como
Ports and Adapters se baseiam nesse princípio, permitindo a troca de implementações com
mínimo impacto, desde que o contrato continue sendo respeitado.

Métodos implementados: exemplo prático

  1. Passo 1: Criar struct Quadrado com campo Lado do tipo float64
  2. Passo 2: Criar struct Círculo com campo Raio
  3. Passo 3: Adicionar método Área() para cada struct, retornando o
    cálculo específico
  4. Passo 4: Criar interface Forma com assinatura do método Área
  5. Passo 5: Criar função calcularArea(Forma) que recebe a
    interface como parâmetro

Expandindo Interfaces com múltiplos métodos

Podemos evoluir a interface Forma e incluir também o método Perímetro. Se um tipo não
implementar todos os métodos, ele será incompatível.

Erro comum

Remover um dos métodos do tipo — como Perímetro — gera erro de compilação, pois o
contrato não é mais respeitado.

Funções genéricas usando interfaces

Ao receber uma interface como parâmetro, uma função passa a aceitar qualquer tipo
compatível. Isso reduz duplicação e centraliza comportamentos.

Testes com interfaces simuladas

Interfaces também facilitam testes unitários. Você pode criar uma implementação falsa
(mock) do contrato para simular comportamentos sem depender de funções reais.

Dica de Teste

Crie mocks que retornam valores previsíveis e use-os para validar a lógica de funções
que dependem da interface.

Interfaces e Clean Architecture

Em arquiteturas limpas, interfaces separam comportamentos das dependências externas.
Isso aumenta a testabilidade do domínio e a flexibilidade nas trocas de componentes.

Bindings dinâmicos com interface

Go permite alternar contexto de execução usando interfaces. Basta o tipo seguir a
assinatura desejada. O binding (ligação) é automático e dinâmico.

Encapsulamento com interface

A implementação de métodos fica escondida do restante do software. O código depende
apenas da interface, promovendo encapsulamento natural.

Mudanças para crescimento do projeto

Conforme o projeto cresce, o uso de interfaces permite adicionar novas formas,
comportamentos e algoritmos sem afetar as dependências existentes.

Resumo das boas práticas

Defina interfaces pequenas, bem nomeadas, com comportamentos específicos. Não exponha
métodos desnecessários. Use composição para combiná-las em casos complexos.

Checklist de Implementação

  • Criou structs com comportamentos distintos
  • Implementou métodos com receivers apropriados
  • Declarou interface com os métodos corretos
  • Usou interface como parâmetro em funções
  • Testou chamada polimórfica com tipos diferentes
  • Criou mocks para simular comportamentos
  • Validou erros na ausência de métodos obrigatórios