Vérification de la rationalité de l'interface

Valider la conformité de l'interface lors de la compilation. Cela inclut :

  • Vérifier le type exporté qui implémente une interface spécifique en tant que partie de l'API de l'interface
  • Les types (à la fois exportés et non exportés) qui implémentent la même interface appartiennent à la collection de types implémentant
  • Tous les scénarios violant la vérification de la rationalité de l'interface interrompront la compilation et informeront l'utilisateur

Supplément : Les trois points ci-dessus sont les mécanismes de vérification de l'interface du compilateur. L'idée générale est que les erreurs dans l'utilisation de l'interface seront signalées lors de la compilation. Par conséquent, ce mécanisme peut être utilisé pour exposer certains problèmes lors de la compilation.

Approche non recommandée :

// Si Handler n'implémente pas http.Handler, une erreur se produira lors de l'exécution
type Handler struct {
  // ...
}
func (h *Handler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  ...
}

Approche recommandée :

type Handler struct {
  // ...
}
// Utilisé pour déclencher le mécanisme de vérification de la rationalité de l'interface lors de la compilation
// Si Handler n'implémente pas http.Handler, une erreur se produira lors de la compilation
var _ http.Handler = (*Handler)(nil)
func (h *Handler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  // ...
}

Si *Handler ne correspond pas à l'interface de http.Handler, l'instruction var _ http.Handler = (*Handler)(nil) ne se compilera pas.

Le côté droit de l'assignation devrait être la valeur nulle du type affirmé. Pour les types pointeurs (comme *Handler), les tranches et les cartes, c'est nil; pour les types de structure, c'est une structure vide.

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