【问题标题】:Defining an interface method with interface return type使用接口返回类型定义接口方法
【发布时间】:2014-12-24 19:18:24
【问题描述】:

TLDR如果您尝试运行它,下面是一个演示问题的游乐场:https://play.golang.org/p/myQtUVg1iq

我正在制作一个 REST API,并且有许多类型的资源可以通过 GET 请求检索

GET http://localhost/api/users
GET http://localhost/api/groups

我有一个模型包,它抽象了不同资源的实现方式:

func(m *UserManager) Get() []Users {
    // Internal logic, assume returns correct results
}

func(m *GroupManager) Get() []Groups {
    // Internal logic, assume returns correct results
}

路由文件设置所有路由和处理程序:

users := models.UserManager{}
groups := models.GroupManager{}

func GetUsersHandler (w http.ResponseWriter, r *http.Request) {
    users := users.Get()
    // Implementation details, writing to w as JSON
}

func GetGroupsHandler (w http.ResponseWriter, r *http.Request) {
    groups := groups.Get()
    // Implementation details, writing to w as JSON
}

func registerRoutes(r *mux.Router) {
    r.handleFunc("/api/users", GetUsersHandler).Method("GET")
    r.handleFunc("/api/groups", GetGroupsHandler).Method("GET")
}

我试图通过创建一个接口来使其更通用,然后只需要一个 GetHandler。像这样的:

type Getter interface {
    Get() []interface{}
}

func GetHandler(g Getter) {
    return func(w http.ResponseWriter, r *http.Request) {
        results := g.Get()
        // Implementation details, writing to w as JSON
    }
}

func registerRoutes(r *mux.Router) {
    r.handleFunc("/api/users", GetHandler(&users)).Method("GET")
    r.handleFunc("/api/groups", GetHandler(&groups)).Method("GET")
}

这真的很接近工作,唯一的问题是模型的返回类型是特定的对象类型,但接口只使用接口返回类型。有什么办法可以在不让模型返回[]interface{}的情况下解决这个问题?

https://play.golang.org/p/myQtUVg1iq

【问题讨论】:

标签: go gorilla


【解决方案1】:

尽量不要像其他 OOP 语言那样处理问题。在 Go 中不能有协变容器,所以要么必须使用空的 interface{},要么必须以不同的方式构建程序。

如果您的Get 方法不同,并且您想在接口中对类型进行分组,请使用另一种方法(有时我们甚至为接口提供 noop 方法),或者只是将usersgroups 作为@ 传递987654326@。无论如何,您都需要在调用链中的某个点进行类型切换或断言,一旦您知道它是什么类型,您就可以相应地处理它。

如果没有更多代码就很难判断,但在这种情况下,最简单的方法可能就是让每种类型本身都是 http.Handler,然后它可以相应地进行调度。

【讨论】:

    【解决方案2】:

    我最终完全避免了这个问题,我没有尝试减少代码量,而是使用 Go 1.4 中的新 go generate 功能来创建每个资源所需的代码。

    【讨论】:

      猜你喜欢
      • 2011-05-16
      • 1970-01-01
      • 2018-02-23
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 2019-02-10
      相关资源
      最近更新 更多