我想知道这里发生了什么事.

有一个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++;
}

根据我的理解,"计数器"类型实现了接口,因为它有一个具有所需签名的方法.到目前一切尚好.然后给出此示例:

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

有人能详细解释一下为什么或者如何将这些不同的功能结合在一起吗?

推荐答案

这是:

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的计数器类型上放置一个方法.这是一个独立于以下示例的示例.

据我所知

没错.

以下函数本身不能作为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是一个接受两个参数(pointer to 101pointer to 102)并且不返回任何内容的函数.换句话说,任何接受这些参数但不返回任何内容的函数都可以是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);

在上行中,通过人为地从函数本身创建一个类型实例,并使该函数成为该实例的ServeHTTP方法,notFound被欺骗为Handler的接口可接受.现在Handle404可以与Handler接口一起使用.这基本上是一种诡计.

Go相关问答推荐

消费者在NAT中是如何实现的

从Kafka到Clickhouse的实时消费数据

Gorm foreign 密钥

Go-Colly:将数据切片为POST请求

Go在使用HTTP代理时如何处理DNS请求?

你能把用户界面文件中的GTK4应用程序窗口添加到GTK4应用程序中吗?

go测试10m后如何避免超时

Golang Fiber Render - 将数据发送到多个布局

Go 中的 protobuf FieldMask 解组

从 eBPF LRU 哈希映射中错误驱逐的元素

使用 LINQ 对内部数组进行排序

在本地 go 应用程序上获取秘密的正确策略

访问传递给可变参数函数的通用 struct 的特定字段

NaN 是 golang 中的可比类型吗?

我如何解码 aes-256-cfb

为什么 0 big.Int 的 .Bytes() 值是空切片?

函数的递归调用以 goroutine 和惯用方式开始,以在所有工作 goroutine 完成时继续调用者

传递上下文的最佳方式

将基本 HTTP AUth 用户/密码凭据存储在 GO 中,无需外部包

Go:如何通过 GIN-Router 从 AWS S3 将文件作为二进制流发送到浏览器?