英文:
How to pass interfaces indirectly in golang
问题
我有一个带有方法的包:
func Route(router *mux.Router){
subrouter := router.PathPrefix(_API).Subrouter()
subrouter.Path(_FOO).HandlerFunc(foo)
subrouter.Path(_BAR).HandlerFunc(bar)
}
我想通过在我的包中拥有一个匹配的接口来移除对mux的外部依赖,该接口简单地包含上述使用的所有功能,如下所示:
type Router interface{
Path(string) Path
PathPrefix(string) Path
}
type Path interface{
HandlerFunc(http.HandlerFunc)
Subrouter() Router
}
func Route(router Router){
subrouter := router.PathPrefix(_API).Subrouter()
subrouter.Path(_FOO).HandlerFunc(foo)
subrouter.Path(_BAR).HandlerFunc(bar)
}
但是当我构建时,我得到错误:
*mux.Router does not implement api.Router (wrong type for Path method)
have Path(string) *mux.Route
want Path(string) api.Path
但是我认为接口在Go中是隐式使用的,所以我认为*mux.Route
实现了我的Path接口。
英文:
I have a package with a method:
func Route(router *mux.Router){
subrouter := router.PathPrefix(_API).Subrouter()
subrouter.Path(_FOO).HandlerFunc(foo)
subrouter.Path(_BAR).HandlerFunc(bar)
}
and I would like to remove the external dependency of mux by having a matching interface in my package that simple encompasses all the functionality used above, like so:
type Router interface{
Path(string) Path
PathPrefix(string) Path
}
type Path interface{
HandlerFunc(http.HandlerFunc)
Subrouter() Router
}
func Route(router Router){
subrouter := router.PathPrefix(_API).Subrouter()
subrouter.Path(_FOO).HandlerFunc(foo)
subrouter.Path(_BAR).HandlerFunc(bar)
}
but when I build this I get error:
>*mux.Router does not implement api.Router (wrong type for Path method)
> have Path(string) *mux.Route
> want Path(string) api.Path
but I thought interfaces were implicitly used in golang so I thought that *mux.Route
did implement my Path interface.
答案1
得分: 5
我认为在Go语言中,接口是隐式使用的。
在特定情况下,值会被隐式地包装在接口中,比如将实现传递给带有接口参数的函数时:
func X(api.Path) {}
X(&mux.Route{}) // 可行,会隐式转换为api.Path
或者从带有接口返回类型的函数返回实现时:
func Y() api.Path {
return &mux.Route{} // 可行,会隐式转换为api.Path
}
在你提出的问题中,编译器希望得到一个具有以下签名方法的值:
Path(string) api.Path
但你提供的值具有以下签名方法:
Path(string) *mux.Route
正如你可能已经知道的,Go类型是不变的。形式上来说:
type A interface { Path(string) *mux.Route }
不是
type B interface { Path(string) api.Path }
的子类型。因此,这样做是行不通的。
英文:
> I thought interfaces were implicitly used in golang
Values are wrapped in interfaces implicitly, but only in specific cases like when passing an implementation to a function with an interface argument:
func X(api.Path) {}
X(&mux.Route{}) // works, implicitly converted to api.Path
or when returning an implementation from a function with an interface return type:
func Y() api.Path {
return &mux.Route{} // works, implicitly converted to api.Path
}
In your question's case the compiler wants a value that has a method with the signature:
Path(string) api.Path
But you're giving it a value with a method with signature:
Path(string) *mux.Route
As you might now, Go types are invariant. Formally:
type A interface { Path(string) *mux.Route }
is not a subtype of
type B interface { Path(string) api.Path }
Therefore this won't work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论