1 回答
TA贡献1772条经验 获得超6个赞
单个函数(在您的示例中为 ,不满足任何接口。func ServeHTTP
因此,将方法附加到函数类型的原因是为了满足接口。
这有什么价值?让任何其他类型实现接口时具有相同的值。让我们看一下界面,因为您提出了这一点。http.Handler
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
例如,您可以使用以下结构来实现此接口:
type myHanlder struct {
/* some fields */
}
func (s *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
/* do things */
}
您也可以使用一些更简单的类型来满足它。比如说,一个字符串:
type myStringHandler string
func (h myStringHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintf(w, "The string is: %s", h)
}
但是,如果您只想直接实现该函数,例如:
func myHandler(w http.ResponseWriter, r *http.Request) {
/* do things */
}
这不能满足界面。因此,我们需要创建一个与函数签名匹配的类型,并提供接口方法。这是做什么的:http.HandlerFunc
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
如果问题是:为什么标准库的作者决定制作一个接口,而不是一个函数类型,而不搜索旧的邮件列表存档中的线索,只有推测是可能的,这在这里真的偏离了主题,但这里有一个小小的尝试:ServerHTTP
接口更易于使用,因为它们可以轻松扩展/嵌入。也就是说,我可以实现一个同时满足接口和其他一些接口的结构。如果不是界面,这将更加繁琐(尽管并非严格不可能)。
http.Handlerhttp.Handler这是惯用语。使用“鸭子打字”的界面正好符合Go的做事方式。也许这有点重复,因为它适合Go的原因是因为它是以这种方式完成的。
如果你有一个复杂的处理程序,它可能跟踪它自己的状态,使用结构是自然的解决方案,并且将其公开为接口比闭包更自然(如果这是作为函数类型实现的,则需要闭包)。
作为一个思想实验,想象一下如果io。读取器接口,其中函数类型:
type Reader func(p []byte) (n int, err error)
我认为很容易看出疯狂会接踵而至。
- 1 回答
- 0 关注
- 111 浏览
添加回答
举报
