简体   繁体   English

go-gin如何调用接口function?

[英]How to call Interface function in go-gin?

This is repository + controller这是存储库 + controller

package brand

import (
    "path/to/models"
    "gorm.io/gorm"

    "github.com/gin-gonic/gin"
)

type ResponseBrand struct {
    Items      []models.MasterBrand `json:"items"`
    TotalCount int                  `json:"total"`
}

type Repository interface {
    GetAll() (ResponseBrand, error)
}

type DBRepo struct {
    db *gorm.DB
}


func (repo *DBRepo) GetAll() (ResponseBrand, error) {
    var response ResponseBrand
    var brands []models.MasterBrand

    repo.db.Find(&brands)

    response.Items = brands
    response.TotalCount = len(brands)

    return response, nil
}

func list(c *gin.Context) {
    // this is an error
    res, _ := Repository.GetAll()
}

This for routing group这用于路由组

func ApplyRoutes(r *gin.RouterGroup) {
    brand := r.Group("/brand") {
        brand.GET("/", list)
    }
}

I try to implement repository in my project, but still stuck to call Repository.GetAll() in our controller function list .我尝试在我的项目中实现存储库,但仍然坚持在我们的 controller function列表中调用Repository.GetAll() i use gin & gorm for this我为此使用杜松子酒和戈姆

Interface is just a set of method signatures that type must have in order to implement that particular interface.接口只是类型为了实现该特定接口而必须具有的一组方法签名。 So you can't call interface.所以你不能调用接口。

In your example code DBRepo is supposed to implement Repository interface and function list() is a function that allows to list contents of any type that implements Repository .在您的示例代码DBRepo应该实现Repository接口和 function list()是一个 function 允许列出实现Repository的任何类型的内容。 In to do so obviously list() needs to know which instance of Repository -like type to list - eg receive it as an argument.这样做显然list()需要知道要列出的Repository类类型的哪个实例 - 例如将其作为参数接收。 Like this:像这样:

func list(ctx *gin.Context, repo Repository) {
    // here call GetAll() which MUST exist on all types passed (otherwise they don't
    // implement Repository interface
    res, _ := repo.GetAll()
    // ...
}

Now gin wouldn't be able to take modified list as a router function because signature of such is just (ctx *gin.Context) but you can use anonymous function and wrap your Repository-aware list() in it.现在gin将无法将修改后的列表作为路由器 function 因为这样的签名只是(ctx *gin.Context)但您可以使用匿名 function 并将您的存储库感知list()包装在其中。

func ApplyRoutes(repo Repository, r *gin.RouterGroup) {
    brand := r.Group("/brand") {
        brand.GET("/", func(ctx *gin.Context) {
            list(repo)
        })
    }
}

Also your ApplyRoutes() function needs to know on which Repository routes should operate - I added it here as argument for simplicity, other elegant solution would be to wrap entire controller in type and obtain the Repository instance as a field of receiver.此外,您的ApplyRoutes() function 需要知道应该在哪些存储库路由上运行 - 为了简单起见,我在这里添加它作为参数,其他优雅的解决方案是将整个 controller 包装在类型中并获取Repository实例作为接收器的字段。

func ApplyRoutes(repo Repository, r *gin.RouterGroup) {
brand := r.Group("/brand") {
    brand.GET("/", func(ctx *gin.Context) {
        list(ctx, repo)
    })
}}

If not, this might work.如果没有,这可能会奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM