在下面的代码段中调用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)
}
}
现在由于某种原因,我必须使用http.Handle()
将指针传递到&templateHandler{filename: "chat.html"}
。如果没有&
,则会出现以下错误:
cannot use (templateHandler literal) (value of type templateHandler)
as http.Handler value in argument to http.Handle:
missing method ServeHTTP
为什么会这样呢?在这种情况下,使用指针有什么区别?
答案 0 :(得分:4)
http.Handle()
期望实现http.Handler
的值(任何值),这意味着它必须具有ServeHTTP()
方法。
您为templateHandler.ServeHTTP()
方法使用了指针接收器,这意味着只有指向templateHandler
的指针值才具有此方法,但没有非指针templateHandler
类型的指针值。
类型可能具有与之关联的方法集。 interface type的方法集是其接口。任何其他类型
T
的方法集都由声明为接收者类型T
的所有methods组成。相应的pointer type*T
的方法集是用接收者*T
或T
声明的所有方法的集合(也就是说,它还包含{{1 }}。
非指针类型仅具有带有非指针接收器的方法。指针类型同时具有指针接收者和非指针接收者的方法。
您的T
方法修改了接收者,因此它必须是一个指针。但是,如果不需要其他处理程序,则可以使用非指针接收器创建ServeHTTP()
方法,在这种情况下,您可以将非指针值用作ServeHTTP()
,就像这样例如:
http.Handler