英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论