如何在golang中间接传递接口

Dan*_*son -1 go

我有一个方法包:

func Route(router *mux.Router){
    subrouter := router.PathPrefix(_API).Subrouter()
    subrouter.Path(_FOO).HandlerFunc(foo)
    subrouter.Path(_BAR).HandlerFunc(bar)
}
Run Code Online (Sandbox Code Playgroud)

我希望通过在我的包中使用匹配的接口来删除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)
}
Run Code Online (Sandbox Code Playgroud)

但是当我构建这个时,我得到错误:

*mux.Router没有实现api.Router(Path方法的类型错误)有Path(string)*mux.Route想要Path(string)api.Path

但我认为接口是在golang中隐式使用的,所以我认为它*mux.Route确实实现了我的Path接口.

thw*_*hwd 5

我认为接口是在golang中隐式使用的

值隐式地包含在接口中,但仅在特定情况下,例如将实现传递给带有interface参数的函数时:

func X(api.Path) {}

X(&mux.Route{}) // works, implicitly converted to api.Path
Run Code Online (Sandbox Code Playgroud)

或者从具有接口返回类型的函数返回实现时:

func Y() api.Path {
    return &mux.Route{} // works, implicitly converted to api.Path
}
Run Code Online (Sandbox Code Playgroud)

在您的问题中,编译器需要一个具有签名方法的值:

Path(string) api.Path
Run Code Online (Sandbox Code Playgroud)

但是你用一个带签名的方法给它一个值:

Path(string) *mux.Route
Run Code Online (Sandbox Code Playgroud)

就像你现在一样,Go类型是不变的.形式上:

type A interface { Path(string) *mux.Route }
Run Code Online (Sandbox Code Playgroud)

不是的子类型

type B interface { Path(string) api.Path }
Run Code Online (Sandbox Code Playgroud)

因此这不起作用.