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 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误