我正在尝试创建一个类似于http.Handler
的界面。对于我的API的某些端点,我需要查询中包含的APNS令牌,或者我需要使用http.StatusBadRequest
进行回复。
我希望类型DeviceHandlerFunc
能够实现ServeHTTP(http.ResponseWriter, *http.Request)
并自动解析令牌并使用令牌调用自身:
type DeviceHandlerFunc func(http.ResponseWriter, *http.Request, string)
func (f DeviceHandlerFunc) ServeHTTP(res http.ResponseWriter, req *http.Request) {
token := req.URL.Query().Get("token")
if token == "" {
http.Error(res, "token missing from query", http.StatusBadRequest)
} else {
f(res, req, token)
}
}
然后从main.go
:
func main() {
mux := http.NewServeMux()
mux.Handle("/", getDevice)
log.Fatal(http.ListenAndServe(":8081", mux))
}
func getDevice(res http.ResponseWriter, req *http.Request, token string) {
// Do stuff with token...
}
这会导致编译错误:
main.go:22:13: cannot use getDevice (type func(http.ResponseWriter, *http.Request, string)) as type http.Handler in argument to mux.Handle:
func(http.ResponseWriter, *http.Request, string) does not implement http.Handler (missing ServeHTTP method)
在我看来,我无法更清楚func(http.ResponseWriter, *http.Request, string)
类型实现http.Handler
。我做错了什么?
示例代码as playground。
答案 0 :(得分:3)
您的DeviceHandlerFunc
类型确实实现了http.Handler
。那不是问题。
但您的getDevice()
函数 类型为DeviceHandlerFunc
,它的类型为func(http.ResponseWriter, *http.Request, string)
(这是一种未命名的类型,显然没有实现{{1} }})。
要使其有效,请使用简单类型conversion:
http.Handler
您可以将mux.Handle("/", DeviceHandlerFunc(getDevice))
转换为getDevice
,因为DeviceHandlerFunc
的基础类型与DeviceHandlerFunc
的类型相同。在Go Playground上尝试。
以下内容也适用:
getDevice
此处var f DeviceHandlerFunc = getDevice
mux.Handle("/", f)
的类型显然是f
。您可以将DeviceHandlerFunc
分配给getDevice
,因为assignability规则适用,即此规则:
[值
f
可分配给x
类型的变量(“T
可分配给x
”)在以下任何情况下:]
T
的类型x
和V
具有相同的基础类型,T
或V
中至少有一个不是已定义的类型。