【问题标题】:Function implementing interface功能实现接口
【发布时间】:2010-12-18 22:55:55
【问题描述】:

我想知道这里发生了什么。

有一个http处理程序的接口:

type Handler interface {
    ServeHTTP(*Conn, *Request)
}

这个实现我想我明白了。

type Counter int

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
    fmt.Fprintf(c, "counter = %d\n", ctr);
    ctr++;
}

据我了解,“Counter”类型实现了接口,因为它有一个具有所需签名的方法。到目前为止,一切都很好。然后给出这个例子:

func notFound(c *Conn, req *Request) {
    c.SetHeader("Content-Type", "text/plain;", "charset=utf-8");
    c.WriteHeader(StatusNotFound);
    c.WriteString("404 page not found\n");
}

// Now we define a type to implement ServeHTTP:
type HandlerFunc func(*Conn, *Request)
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req) // the receiver's a func; call it
}
// Convert function to attach method, implement the interface:
var Handle404 = HandlerFunc(notFound);

有人可以详细说明这些不同功能为何或如何组合在一起?

【问题讨论】:

    标签: go


    【解决方案1】:

    这个:

    type Handler interface {
        ServeHTTP(*Conn, *Request)
    }
    

    表示任何满足Handler 接口的类型都必须具有ServeHTTP 方法。以上将在包内http

    type Counter int
    
    func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
        fmt.Fprintf(c, "counter = %d\n", ctr);
        ctr++;
    }
    

    这会在对应于 ServeHTTP 的 Counter 类型上放置一个方法。这是一个与以下不同的示例。

    据我了解, 类型“计数器”实现 接口,因为它有一个方法 具有所需的签名。

    没错。

    以下函数本身不能用作Handler

    func notFound(c *Conn, req *Request) {
        c.SetHeader("Content-Type", "text/plain;", "charset=utf-8");
        c.WriteHeader(StatusNotFound);
        c.WriteString("404 page not found\n");
    }
    

    这些东西的其余部分正好适合上面的,所以它可以是Handler

    在下文中,HandlerFunc 是一个函数,它接受两个参数,指向Conn 的指针和指向Request 的指针,并且什么都不返回。换句话说,任何接受这些参数但不返回任何内容的函数都可以是HandlerFunc

    // Now we define a type to implement ServeHTTP:
    type HandlerFunc func(*Conn, *Request)
    

    这里ServeHTTP是添加到HandlerFunc类型的方法:

    func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
        f(c, req) // the receiver's a func; call it
    }
    

    它所做的只是使用给定的参数调用函数本身 (f)。

    // Convert function to attach method, implement the interface:
    var Handle404 = HandlerFunc(notFound);
    

    在上面的行中,notFound 已经被Handler 的接口接受,方法是人为地从函数本身创建一个类型实例,并将函数放入实例的ServeHTTP 方法中。现在Handle404 可以与Handler 接口一起使用。这基本上是一种技巧。

    【讨论】:

    • 好吧,我想我现在明白了,让我感到困惑的是 notFound 到 HandlerFunc 的转换。在重新阅读了有效 go 的转换部分之后,更清楚它如何也适用于函数。 golang.org/doc/effective_go.html#conversions
    【解决方案2】:

    下半场你到底有什么不明白的地方?它与上面的模式相同。他们没有将 Counter 类型定义为 int,而是定义了一个名为 notFound 的函数。然后,他们创建了一种名为 HandlerFunc 的函数,该函数接受两个参数,一个连接和一个请求。然后他们创建了一个名为 ServeHTTP 的新方法,该方法绑定到 HandlerFunc 类型。 Handle404 只是使用 notFound 函数的此类的一个实例。

    【讨论】:

    • 是的,这是典型的高阶函数式编程。当您第一次看到它并按照自己的方式处理类型时可能会感到困惑。
    猜你喜欢
    • 2010-11-11
    • 2023-03-07
    • 2020-02-03
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多