【问题标题】:Why use a pointer when using a custom http.Handler in Go?为什么在 Go 中使用自定义 http.Handler 时使用指针?
【发布时间】:2019-11-01 07:41:56
【问题描述】:

在下面的代码 sn-p 中调用 http.Handle() 时,我使用了自己的 templateHandler 类型,它实现了 http.Handler 接口。

package main

import (
    "html/template"
    "log"
    "net/http"
    "path/filepath"
    "sync"
)

type templateHandler struct {
    once     sync.Once
    filename string
    templ    *template.Template
}

func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    t.once.Do(func() {
        t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename)))
    })
    t.templ.Execute(w, nil)
}

func main() {
    http.Handle("/", &templateHandler{filename: "chat.html"})
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

现在出于某种原因,我必须使用 &templateHandler{filename: "chat.html"} 传递指向 http.Handle() 的指针。如果没有&,我会收到以下错误:

cannot use (templateHandler literal) (value of type templateHandler) 
as http.Handler value in argument to http.Handle: 
missing method ServeHTTP

为什么会发生这种情况?在这种情况下使用指针有什么不同?

【问题讨论】:

    标签: pointers go methods interface


    【解决方案1】:

    http.Handle() 需要一个实现http.Handler 的值(任何值),这意味着它必须有一个ServeHTTP() 方法。

    您为templateHandler.ServeHTTP() 方法使用了指针接收器,这意味着只有指向templateHandler 的指针值具有此方法,而不是非指针templateHandler 类型的值。

    Spec: Method sets:

    一个类型可能有一个与之关联的方法集interface type 的方法集是它的接口。任何其他类型T 的方法集由所有声明为接收器类型Tmethods 组成。对应的pointer type*T的方法集是所有用receiver*TT声明的方法的集合(即它还包含T的方法集)。

    非指针类型只有带有非指针接收器的方法。指针类型具有指针和非指针接收器的方法。

    你的ServeHTTP() 方法修改了接收者,所以它必须是一个指针。但如果其他一些处理程序不需要,ServeHTTP() 方法可以使用非指针接收器创建,在这种情况下,您可以使用非指针值作为 http.Handler,如下例所示:

    type myhandler struct{}
    
    func (m myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
    
    func main() {
        // non-pointer struct value implements http.Handler:
        http.Handle("/", myhandler{})
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-24
      • 1970-01-01
      • 2017-03-10
      • 2020-05-04
      • 2015-06-08
      • 2014-01-04
      • 1970-01-01
      • 2018-02-09
      • 2021-07-07
      相关资源
      最近更新 更多