dqqvravff05370501 2018-03-08 01:19
浏览 17
已采纳

覆盖接口的函数回调参数

I am using a package that has a Router interface, and I have created my own app-specific Router interface that wraps the third party package.

Everything is working well, however one of the methods is throwing a compilation error:

controllers/auth.go:52:17: cannot use func literal (type func(router.Router)) as type func(chi.Router) in argument to c.router.Group

This is the interface of the third party package (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

    // ...
}

This is my wrapper interface:

type Router interface {
    chi.Router

    // Custom methods...
}

My usage of the Group function is like so:

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)
    })
}

Why is it screaming at my function callbacks argument type? My wrapper router.Router implements the chi.Router interface, so it should work fine shouldn't it? Am I misunderstanding how Go works here?

  • 写回答

2条回答 默认 最新

  • dpprx26000 2018-03-08 14:27
    关注

    I can see how this can be confusing so I will try to break it down. You have this method:

    Group(fn func(r Router)) Router
    

    This method takes a function as a parameter. That function must have a specific signature:

    func(r Router)
    

    That is, it takes a single argument of type chi.Router and has no return values. However, when you call it:

    c.router.Group(func(r router.Router) { /***/ }
    

    You're passing in a function of the wrong signature; your function signature is:

    func(r router.Router)
    

    That's not the signature required by the method you're calling, so it won't compile. It doesn't matter if router.Router implements chi.Router; the parameter (a func(router.Router)) passed is not of the expected type (a func(chi.Router)).

    This may seem silly at first - after all, any router.Router must implement chi.Router. But, think about it: that method, Group, is expecting to receive a function, to which it can pass any chi.Router. That means it can pass a chi.Router which does not implement router.Router. If it were to accept your function, it would break type safety, and what in Go is meant to be a compile-time error (the error you're getting, in fact) would become a run-time error. Basically, by passing a function with a different (and more strict) argument type, you're expecting a guarantee which that method never offered.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 求chat4.0解答一道线性规划题,用lingo编程运行,第一问要求写出数学模型和lingo语言编程模型,第二问第三问解答就行,我的ddl要到了谁来求了
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果