去功能打字

thw*_*hwd 5 types function go

对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变的实例HandlerFuncfoo作为其ServeHTTP方法.现在我真的很困惑这是如何工作的.

如果我在一个类型上有多个方法,我怎么知道哪个方法将附加到新实例以及名称或顺序?

rua*_*akh 8

这种方法允许您在期望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变的实例HandlerFuncfoo作为其ServeHTTP方法.现在我真的很困惑这是如何工作的.

首先,它更正确的说,你已经转换随机函数foo 输入HandlerFunc,而不是你传递函数 HandlerFunc好像HandlerFunc是一个功能.(HandlerFunc(foo)符号是一个类型转换;你也可以写,var bar HandlerFunc = foo并让转换隐式发生.)

其次,它更正确的说,bar有一个ServeHTTP是方法调用 foo,比foo本身实际上ServeHTTP方法.

那有意义吗?