我正在使用一个具有 Router
接口的软件包,并且我创建了自己的特定于应用程序的 Router
接口来包装第三方软件包 .
一切都运行良好,但其中一个方法是抛出一个编译错误:
controllers / auth.go:52:17:不能在c.router.Group的参数中使用func文字(类型为func(router.Router))作为类型func(chi.Router)
这是第三方包(chi)的界面:
type Router interface {
// ...
// Group adds a new inline-Router along the current routing
// path, with a fresh middleware stack for the inline-Router.
Group(fn func(r Router)) Router
// ...
}
这是我的包装器界面:
type Router interface {
chi.Router
// Custom methods...
}
我对 Group
函数的用法如下:
type AuthController struct {
router router.Router
// ...
}
func (c *AuthController) SetRoutes() {
c.router.Group(func(r router.Router) {
r.Use(middleware.Anyone)
r.Post("/auth/register", c.Register)
r.Post("/auth/login", c.Authenticate)
r.Post("/auth/token/refresh", c.RefreshToken)
})
c.router.Group(func(r router.Router) {
r.Use(middleware.Authorized)
r.Get("/auth/ping", c.Ping)
r.Post("/auth/logout", c.Logout)
})
}
为什么它在我的函数回调参数类型中尖叫?我的包装 router.Router
实现了 chi.Router
接口,所以它应该可以正常工作不应该吗?我误解了Go如何在这里工作吗?
2 回答
我可以看出这可能会让人感到困惑,所以我会尝试将其分解 . 你有这个方法:
此方法将函数作为参数 . 该功能必须具有特定的签名:
也就是说,它需要一个类型为
chi.Router
的参数,并且没有返回值 . 但是,当你打电话给它时:你传递的是错误签名的功能;你的功能签名是:
那个's not the signature required by the method you'正在调用,所以如果
router.Router
实现chi.Router
,它就会赢得't compile. It doesn';传递的参数(afunc(router.Router)
)不是预期的类型(func(chi.Router)
) .这一开始可能看起来很愚蠢 - 毕竟,任何
router.Router
都必须实施chi.Router
. 但是,考虑一下:那个方法Group
期待接收一个函数,它可以传递给任何函数chi.Router
. 这意味着它可以传递chi.Router
,它不实现router.Router
. 如果要接受你的函数,它会破坏类型安全性,而Go中的内容是编译时错误(错误是你希望保证该方法永远不会提供的) .即使您的接口包含来自其他包的接口(类型必须完全匹配),参数类型也不符合预期 . 您需要让函数采用
chi.router
,然后使用类型断言(即myRouter := r.(Router)
)转换为您的类型 .