在开发interface时,要对interface的合理性进行验证,在编译时验证接口的符合性。这包括:
- 将实现特定接口的导出类型作为接口API的一部分进行检查
- 实现同一接口的(导出和非导出)类型属于实现类型的集合
- 任何违反接口的合理性检查的场景,都会终止编译,并通知给用户
补充:以上3条是编译器对接口的检查机制,大体意思是错误的使用接口会被编译器报错。所以可以利用这个机制让部门问题提前暴露。
源代码
// 如果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,
) {
// ...
}