我想创建一个可以作为http
的HandleFunc的函数,但也可以使用另一个编写器调用。
由于http.ResponseWriter
实现了io.Writer
并且我的函数不需要设置HTTP头,我认为这可能是:
func doit(w io.Writer, r *http.Request) {
w.Write([]byte("Hello"))
}
http.HandleFunc("/", doit)
但不是:
不能在http.HandleFunc的参数中使用doit(类型func(io.Writer,* http.Request))作为类型func(http.ResponseWriter,* http.Request)
这是有道理的,因为它需要一个类型断言来使io.Writer与预期的http.ResponseWriter兼容。
这样的功能可能吗?
答案 0 :(得分:4)
函数类型表示具有相同参数和结果类型的所有函数的集合。
您的doit()
函数不符合http.HandlerFunc
条件,因为参数类型不匹配。类型io.Writer
和http.ResponseWriter
是两种完全不同的类型,因此采用这些类型的函数类型也不同。
但是,由于接口类型io.Writer
的{{3}}是http.ResponseWriter
方法集的子集,因此后一种类型的值可以是method set前一种变量。
您可以将其包装在http.HandlerFunc
类型的匿名函数中,该函数可以只调用doit()
,然后您可以将其用作http.HandlerFunc
:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
doit(w, r)
})
如果你需要这么多次,你可以创建一个辅助函数来产生http.HandlerFunc
函数值:
func wrap(f func(w io.Writer, r *http.Request)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
f(w, r)
}
}
然后使用它只是:
http.HandleFunc("/", wrap(doit))
Handler
类型另一种选择是定义您自己的函数类型,您可以附加一个简单的方法来实现assigned(即ServeHTTP()
),并使用简单类型http.Handler
您可以将您的功能注册为处理程序:
type SimpleHandler func(io.Writer, *http.Request)
func (sh SimpleHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
sh(w, r)
}
使用它:
http.Handle("/", SimpleHandler(doit))
请注意,表达式SimpleHandler(doit)
只是一种类型转换,它不是函数调用。因此,在后台没有创建新值或匿名函数,此解决方案效率最高。