实现接口的函数

huangapple go评论88阅读模式
英文:

Function implementing interface

问题

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

这是一个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");
}

// 现在我们定义一个类型来实现ServeHTTP:
type HandlerFunc func(*Conn, *Request)
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req) // 调用接收者是一个函数
}
// 将函数转换为附加方法,实现接口:
var Handle404 = HandlerFunc(notFound);

有人可以详细说明这些不同的函数是如何组合在一起的吗?

英文:

I want to know what is happening here.

There is the interface for a http handler:

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

This implementation I think I understand.

type Counter int

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

From my understanding it is that the type "Counter" implements the interface since it has a method that has the required signature. So far so good. Then this example is given:

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);

Can somebody elaborate on why or how these various functions fit together?

答案1

得分: 25

这个代码片段中,Handler 接口规定了任何满足该接口的类型必须拥有 ServeHTTP 方法。上述代码位于 http 包中。

type Counter int

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

上述代码在 Counter 类型上定义了一个与 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

// 现在我们定义一个类型来实现 ServeHTTP:
type HandlerFunc func(*Conn, *Request)

在上述代码中,ServeHTTP 是添加到 HandlerFunc 类型的方法:

func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
    f(c, req) // 调用函数本身(`f`)并传入参数
}

它只是调用了函数本身(f)并传入了给定的参数。

// 将函数转换为附加方法,实现接口:
var Handle404 = HandlerFunc(notFound)

在上述代码中,通过人为地创建一个类型实例,并将函数本身转换为该实例的 ServeHTTP 方法,将 notFound 调整为适用于 Handler 接口。现在,Handle404 可以与 Handler 接口一起使用。这基本上是一种技巧。

英文:

This:

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

says that any type which satisfies the Handler interface must have a ServeHTTP method. The above would be inside the package http.

type Counter int

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

This puts a method on the Counter type which corresponds to ServeHTTP. This is an example which is separate from the following.

> From my understanding it is that the
> type "Counter" implements the
> interface since it has a method that
> has the required signature.

That's right.

The following function by itself won't work as a 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");
}

The rest of this stuff is just fitting the above so that it can be a Handler.

In the following, a HandlerFunc is a function which takes two arguments, pointer to Conn and pointer to Request, and returns nothing. In other words, any function which takes these arguments and returns nothing can be a HandlerFunc.

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

Here ServeHTTP is a method added to the type HandlerFunc:

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

All it does is to call the function itself (f) with the arguments given.

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

In the above line, notFound has been finagled into being acceptable for the interface for Handler by artificially creating a type instance out of the function itself and making the function into the ServeHTTP method for the instance. Now Handle404 can be used with the Handler interface. It's basically a kind of trick.

答案2

得分: -2

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

英文:

What exactly don't you understand about the second half? It's the same pattern as above. Instead of defining the Counter type as an int, they define a function called notFound. They then create a type of function called HandlerFunc that takes two parameters, a connection and a request. they then create a new method called ServeHTTP, that gets bound to the HandlerFunc type. Handle404 is simply an instance of this class that uses the notFound function.

huangapple
  • 本文由 发表于 2009年11月21日 09:44:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/1774225.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定