Golang中函数参数的使用与技巧
Golang中函数参数的使用与技巧

为了方便,我想通过创建一个如下结构体来缩短 AddHandler 的函数参数:

并用这个结构体代替 w http.ResponseWriter, r *http.Request 参数。
一切看起来都没问题,但我该如何处理这个错误?

这个错误之所以出现,是因为 http.HandleFunc 只能接受参数为 w http.ResponseWriter, r *http.Request 的处理函数:

更多关于Golang中函数参数的使用与技巧的实战教程也可以访问 https://www.itying.com/category-94-b0.html
有几种方法可以实现这个功能:
传递给 AddHandler 的函数可以将这些值包装到一个 CoronavirusRelay 结构体中,然后调用另一个处理函数:
type CoronavirusRelay {
request *http.Request
writer http.ResponseWriter
}
func myCoronavirusRelayFunc(CoronavirusRelay cr) {
// ...
}
func main() {
// ...
s.AddHandler("/test", func(w http.ResponseWriter, r *http.Request) {
myCoronavirusRelayFunc(CoronavirusRelay{request: r, writer: w})
})
// ...
}
如果你需要频繁这样做,可能需要一个工厂函数:
func CoronavirusRelayFunc(f func(cr CoronavirusRelay)) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
f(CoronavirusRelay{reader: r, writer: w})
}
}
func main() {
// ...
s.AddHandler("/test", CoronavirusRelayFunc(myCoronavirusRelayFunc))
s.AddHandler("/test2", CoronavirusRelayFunc(myCoronavirusRelayFunc2))
// etc ...
}
更多关于Golang中函数参数的使用与技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中,http.HandleFunc 要求处理函数的签名必须是 func(http.ResponseWriter, *http.Request)。要使用自定义结构体作为参数,可以通过适配器模式或闭包来包装处理函数。以下是两种解决方案:
方案1:使用适配器函数
创建一个适配器函数,将自定义结构体处理函数转换为标准 http.HandlerFunc。
package main
import (
"net/http"
)
// 自定义结构体
type HandlerArgs struct {
W http.ResponseWriter
R *http.Request
}
// 自定义处理函数类型
type CustomHandler func(HandlerArgs)
// 适配器:将 CustomHandler 转换为 http.HandlerFunc
func AdaptHandler(h CustomHandler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
args := HandlerArgs{W: w, R: r}
h(args)
}
}
// 示例处理函数
func MyHandler(args HandlerArgs) {
args.W.WriteHeader(http.StatusOK)
args.W.Write([]byte("Hello with custom struct"))
}
func main() {
http.HandleFunc("/", AdaptHandler(MyHandler))
http.ListenAndServe(":8080", nil)
}
方案2:使用闭包直接包装
在注册路由时,通过闭包将自定义结构体处理函数嵌入标准签名中。
package main
import (
"net/http"
)
type HandlerArgs struct {
W http.ResponseWriter
R *http.Request
}
func MyHandler(args HandlerArgs) {
args.W.WriteHeader(http.StatusOK)
args.W.Write([]byte("Hello with closure"))
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
args := HandlerArgs{W: w, R: r}
MyHandler(args)
})
http.ListenAndServe(":8080", nil)
}
这两种方案都允许在保持 http.HandleFunc 兼容性的同时使用自定义结构体参数。适配器方案更适用于多个路由重用,闭包方案则更直接灵活。

