使用接口返回类型定义接口方法

时间:2014-12-24 19:18:24

标签: go gorilla

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

2 个答案:

答案 0 :(得分:0)

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

如果您的Get方法不同并且您想要在接口中对类型进行分组,请使用其他方法(有时我们甚至只为接口使用noop方法),或者只传入users或{{ 1}}作为groups。您无论如何都需要在调用链中的某个位置进行类型切换或断言,一旦您知道它是什么类型,您就可以相应地处理它。

没有更多代码很难分辨,但在这种情况下,最简单的路径可能就是让每个类型都是http.Handler本身,并且可以相应地调度。

答案 1 :(得分:0)

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