使用接受 io.Writer 作为 HandleFunc 的函数
Use function that accepts io.Writer as HandleFunc
我想创建一个函数,它可以是 http
的 HandleFunc,但也可以被其他作者调用。
由于http.ResponseWriter
实现了io.Writer
并且我的函数不需要设置HTTP头,所以我认为这可能是可能的:
func doit(w io.Writer, r *http.Request) {
w.Write([]byte("Hello"))
}
http.HandleFunc("/", doit)
但是没有:
cannot use doit (type func(io.Writer, *http.Request)) as type func(http.ResponseWriter, *http.Request) in argument to http.HandleFunc
这是有道理的,因为它需要类型断言才能使 io.Writer 与预期的 http.ResponseWriter 兼容。
函数可以实现类似的功能吗?
A function type denotes the set of all functions with the same parameter and result types.
你的doit()
函数不符合http.HandlerFunc
because parameter types do not match. The types io.Writer
and http.ResponseWriter
是2种完全不同的类型,所以采用这些类型的函数类型也不同。
使用匿名函数值
但是,由于method set of the interface type io.Writer
is a subset of the method set of http.ResponseWriter
, a value of the latter type can be assigned前的变量类型。
您可以将其包装在类型为 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
类型
另一个选择是定义你自己的函数类型,你可以附加一个简单的方法来实现http.Handler
(namely ServeHTTP()
), and that way with a simple type conversion你可以将你的函数注册为处理程序:
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)
只是类型转换,不是函数调用。所以这里没有在后台创建新值或者匿名函数,这个方案效率最高
我想创建一个函数,它可以是 http
的 HandleFunc,但也可以被其他作者调用。
由于http.ResponseWriter
实现了io.Writer
并且我的函数不需要设置HTTP头,所以我认为这可能是可能的:
func doit(w io.Writer, r *http.Request) {
w.Write([]byte("Hello"))
}
http.HandleFunc("/", doit)
但是没有:
cannot use doit (type func(io.Writer, *http.Request)) as type func(http.ResponseWriter, *http.Request) in argument to http.HandleFunc
这是有道理的,因为它需要类型断言才能使 io.Writer 与预期的 http.ResponseWriter 兼容。
函数可以实现类似的功能吗?
A function type denotes the set of all functions with the same parameter and result types.
你的doit()
函数不符合http.HandlerFunc
because parameter types do not match. The types io.Writer
and http.ResponseWriter
是2种完全不同的类型,所以采用这些类型的函数类型也不同。
使用匿名函数值
但是,由于method set of the interface type io.Writer
is a subset of the method set of http.ResponseWriter
, a value of the latter type can be assigned前的变量类型。
您可以将其包装在类型为 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
类型
另一个选择是定义你自己的函数类型,你可以附加一个简单的方法来实现http.Handler
(namely ServeHTTP()
), and that way with a simple type conversion你可以将你的函数注册为处理程序:
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)
只是类型转换,不是函数调用。所以这里没有在后台创建新值或者匿名函数,这个方案效率最高