我对HTTP包中的这些代码感到困惑:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
Run Code Online (Sandbox Code Playgroud)
为什么该ServeHTTP方法具有与其类型完全相同的签名 - 重点是什么?
测试,我发现如果我将一个随机函数(foo)传递给HandlerFunc:
var bar = HandlerFunc(foo)
Run Code Online (Sandbox Code Playgroud)
bar变的实例HandlerFunc与foo作为其ServeHTTP方法.现在我真的很困惑这是如何工作的.
如果我在一个类型上有多个方法,我怎么知道哪个方法将附加到新实例以及名称或顺序?
这种方法允许您在期望a的上下文中使用函数Handler.
会发生什么,有一个Handler界面:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Run Code Online (Sandbox Code Playgroud)
并声明各种函数接受声明属于此接口的参数 - 例如:
func TimeoutHandler(h Handler, ns int64, msg string) Handler {
f := func() <-chan int64 {
return time.After(ns)
}
return &timeoutHandler{h, f, msg}
}
Run Code Online (Sandbox Code Playgroud)
这意味着,当你调用这样的功能,你必须属于一个类型的对象通过满足这个接口,这就是说,具有一种ServeHTTP与适当的签名方法.(在Go中,与某些语言不同,类型不需要显式实现接口,它只需要具有接口指定的方法.)
那么,你引用的代码片段:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
Run Code Online (Sandbox Code Playgroud)
创建一个HandlerFunc基于func(ResponseWriter, *Request)的类型,但使用一个ServeHTTP使用适当签名调用的方法来扩充类型,以便它满足Handler接口.此ServeHTTP方法只调用函数本身.因此,如果f是具有正确签名的函数,您可以编写如下内容:
var h HandlerFunc = f // h == f, but converted to a HandlerFunc
// so it satisfies the Handler interface.
TimeoutHandler(h, 1000000, "timed out")
Run Code Online (Sandbox Code Playgroud)
澄清一些关于此的事情:
测试,我发现如果我将一个随机函数(
foo)传递给HandlerFunc:var bar = HandlerFunc(foo)
bar变的实例HandlerFunc与foo作为其ServeHTTP方法.现在我真的很困惑这是如何工作的.
首先,它更正确的说,你已经转换随机函数foo 输入HandlerFunc,而不是你传递函数来 HandlerFunc好像HandlerFunc是一个功能.(HandlerFunc(foo)符号是一个类型转换;你也可以写,var bar HandlerFunc = foo并让转换隐式发生.)
其次,它更正确的说,bar有一个ServeHTTP是方法调用 foo,比foo本身实际上是该ServeHTTP方法.
那有意义吗?