Interface Rationality Verification

Validate the compliance of the interface at compile time. This includes:

  • Checking the exported type that implements a specific interface as part of the interface API
  • The types (both exported and non-exported) that implement the same interface belong to the collection of implementing types
  • Any scenarios that violate the interface rationality check will terminate compilation and notify the user

Supplement: The above three points are the interface check mechanisms of the compiler. The general idea is that errors in using the interface will be reported at compile time. Therefore, this mechanism can be used to expose some problems at compile time.

Not recommended approach:

// If Handler does not implement http.Handler, an error will occur at runtime
type Handler struct {
  // ...
}
func (h *Handler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  ...
}

Recommended approach:

type Handler struct {
  // ...
}
// Used to trigger the interface rationality check mechanism at compile time
// If Handler does not implement http.Handler, an error will occur at compile time
var _ http.Handler = (*Handler)(nil)
func (h *Handler) ServeHTTP(
  w http.ResponseWriter,
  r *http.Request,
) {
  // ...
}

If *Handler does not match the interface of http.Handler, the statement var _ http.Handler = (*Handler)(nil) will not compile.

The right side of the assignment should be the zero value of the asserted type. For pointer types (such as *Handler), slices, and maps, this is nil; for structure types, this is an empty structure.

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