Verificação de Racionalidade da Interface

Validar a conformidade da interface em tempo de compilação. Isso inclui:

  • Verificar o tipo exportado que implementa uma interface específica como parte da API da interface
  • Os tipos (tanto exportados quanto não exportados) que implementam a mesma interface pertencem à coleção de tipos implementadores
  • Quaisquer cenários que violem a verificação da racionalidade da interface irão encerrar a compilação e notificar o usuário

Suplemento: Os três pontos acima são mecanismos de verificação da interface do compilador. A ideia geral é que os erros ao usar a interface serão relatados em tempo de compilação. Portanto, esse mecanismo pode ser usado para expor alguns problemas em tempo de compilação.

Abordagem não recomendada:

// Se Handler não implementar http.Handler, um erro ocorrerá em tempo de execução
type Handler struct {
  // ...
}
func (h *Handler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  ...
}

Abordagem recomendada:

type Handler struct {
  // ...
}
// Usado para acionar o mecanismo de verificação da racionalidade da interface em tempo de compilação
// Se Handler não implementar http.Handler, um erro ocorrerá em tempo de compilação
var _ http.Handler = (*Handler)(nil)
func (h *Handler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  // ...
}

Se *Handler não corresponder à interface de http.Handler, a declaração var _ http.Handler = (*Handler)(nil) não será compilada.

O lado direito da atribuição deve ser o valor zero do tipo afirmado. Para tipos de ponteiro (como *Handler), slices e maps, isso é nil; para tipos de estrutura, isso é uma estrutura vazia.

type LogHandler struct {
  h   http.Handler
  log *zap.Logger
}
var _ http.Handler = LogHandler{}
func (h LogHandler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  // ...
}