Проверка рациональности интерфейса
Проверка соответствия интерфейса на этапе компиляции. Это включает в себя:
- Проверку экспортируемого типа, который реализует конкретный интерфейс в рамках API интерфейса
- Типы (как экспортируемые, так и неэкспортируемые), реализующие тот же интерфейс, принадлежат к коллекции реализующих типов
- Любые сценарии, нарушающие проверку рациональности интерфейса, приведут к остановке компиляции и уведомлению пользователя
Дополнение: Вышеперечисленные три пункта - это механизмы проверки интерфейса компилятора. Общая идея заключается в том, что ошибки при использовании интерфейса будут сообщаться на этапе компиляции. Поэтому этот механизм может быть использован для выявления некоторых проблем на этапе компиляции.
Не рекомендуемый подход:
// Если Handler не реализует http.Handler, произойдет ошибка во время выполнения
type Handler struct {
// ...
}
func (h *Handler) ServeHTTP(
w http.ResponseWriter,
r *http.Request,
) {
...
}
Рекомендуемый подход:
type Handler struct {
// ...
}
// Используется для запуска механизма проверки интерфейса на рациональность на этапе компиляции
// Если Handler не реализует http.Handler, произойдет ошибка на этапе компиляции
var _ http.Handler = (*Handler)(nil)
func (h *Handler) ServeHTTP(
w http.ResponseWriter,
r *http.Request,
) {
// ...
}
Если *Handler
не соответствует интерфейсу http.Handler
, оператор var _ http.Handler = (*Handler)(nil)
не будет компилироваться.
Справа от присваивания должно быть нулевое значение утвержденного типа. Для типов указателей (например, *Handler
), срезов и карт это nil
; для типов структур это пустая структура.
type LogHandler struct {
h http.Handler
log *zap.Logger
}
var _ http.Handler = LogHandler{}
func (h LogHandler) ServeHTTP(
w http.ResponseWriter,
r *http.Request,
) {
// ...
}