[英]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.