And*_*eKR 2 lambda interface go type-assertion
我想制作一个可以作为 HandleFunc 的函数,http但也可以被其他作者调用。
由于http.ResponseWriter实现io.Writer和我的函数不需要设置 HTTP 标头,我认为这可能是可能的:
func doit(w io.Writer, r *http.Request) {
w.Write([]byte("Hello"))
}
http.HandleFunc("/", doit)
Run Code Online (Sandbox Code Playgroud)
但不是:
不能在 http.HandleFunc 的参数中使用 doit (type func(io.Writer, *http.Request)) 作为类型 func(http.ResponseWriter, *http.Request)
这是有道理的,因为它需要类型断言才能使 io.Writer 与预期的 http.ResponseWriter 兼容。
函数可以实现类似的功能吗?
函数类型表示具有相同参数和结果类型的所有函数的集合。
您的doit()函数不符合 an 的条件,http.HandlerFunc因为参数类型不匹配。的类型io.Writer和http.ResponseWriter2种完全不同的类型,所以服用这些类型的功能的类型也不同。
然而,由于该方法集的接口类型的io.Writer是设置的方法的一个子集http.ResponseWriter,后者类型的值可以被分配给前一类型的变量。
您可以将它包装在一个匿名函数中,http.HandlerFunc该函数可以简单地调用doit(),然后您可以将它用作http.HandlerFunc:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
doit(w, r)
})
Run Code Online (Sandbox Code Playgroud)
如果您多次需要此功能,您可以创建一个辅助函数来生成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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它很简单:
http.HandleFunc("/", wrap(doit))
Run Code Online (Sandbox Code Playgroud)
Handler类型另一种选择是定义您自己的函数类型,您可以附加一个简单的方法来实现http.Handler(即ServeHTTP()),这样通过简单的类型转换,您就可以将您的函数注册为处理程序:
type SimpleHandler func(io.Writer, *http.Request)
func (sh SimpleHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
sh(w, r)
}
Run Code Online (Sandbox Code Playgroud)
使用它:
http.Handle("/", SimpleHandler(doit))
Run Code Online (Sandbox Code Playgroud)
请注意,表达式SimpleHandler(doit)只是一种类型转换,而不是函数调用。所以这里没有在后台创建新的值或匿名函数,这个解决方案是最有效的。
| 归档时间: |
|
| 查看次数: |
1057 次 |
| 最近记录: |