gpt4 book ai didi

go - 是否可以将结构的 slice 作为接口(interface)传递给方法?

转载 作者:行者123 更新时间:2023-12-01 21:13:54 24 4
gpt4 key购买 nike

我在 Go 中编写了一个简单的 API,使用 github.com/gin-gonic/gin .它由数据库支持,我正在使用 github.com/jinzhu/gorm用于查询和更新数据库。

我有许多端点几乎使用相同的代码从数据库中获取数据,所以我试图创建一个 retrieve适用于我所有数据库类型的方法。

例如,我有以下结构:

type Image struct {
gorm.Model
Name string
Filename string
}

我的路线的 API 声明如下:
func (v1 *ApiV1) getImage(c *gin.Context) {
var images []db.Image

httpStatus := v1.retrieve("name", c.Param("name"), &images)

c.JSON(
httpStatus,
images,
)
}

可以看出,我正在尝试将指针传递给我希望查询填充的结构。由于数据库中的不同类型需要几个不同的端点,我想制作 retrieve方法可重用,所以我用这个签名创建了它:
func (v1 *ApiV1) retrieve(fieldName string, name string, returnObject *[]interface{}) int {

// create var to hold the http status
var httpStatus int = http.StatusOK

// determine if a name has been passed
if name == "" {
v1.app.DB.Find(returnObject)
} else {

// look for the name in the database
v1.app.DB.Where(fieldName+" = ?", name).First(returnObject)

// if the name cannot be found then set the status to 404
if len(*returnObject) == 0 {
httpStatus = http.StatusNotFound
}
}

return httpStatus
}

为了尝试使其“通用”,我使用了 *[]interface{}作为 returnObject 的类型。 (这个名字有点用词不当,因为它是指针,但它很容易理解某些东西会被更新)。

但是,当我运行它时,我收到以下错误:
cannot use &images (type *[]db.Image) as type *[]interface {} in argument to v1.retrieve

我完全理解 Go 是一种严格类型的语言,但我希望能够重用我的 retrieve函数我需要能够传入一个指向 slice (任何类型)的指针,Gorm 在运行查询时可以填充该 slice 。

我目前正在从一个版本中重构它,该版本确实具有用于检索每个 API 端点的单独函数,但显然这效率低下并且使得执行任何重构变得更加困难。

那么我要问的可能吗?

最佳答案

感谢@mkopriva(并从查看代码中休息一下),我能够弄清楚如何获得可重复使用的检索功能。

如评论中所述,我试图比较 []T[]I这是行不通的。所以我通过代码重构使用 GORM 链中的表名,这意味着结果现在可以是一个接口(interface),并且它作为返回项而不是指针传递回来。

所以现在我的retrieve方法看起来像:

func (v1 *ApiV1) retrieve(tableName string, fieldName string, name string) ([]interface{}, int) {

// create var to hold the http status
var httpStatus int = http.StatusOK
var result []interface{}

// determine if a name has been passed
if name == "" {
v1.app.DB.Find(result)
} else {

// look for the name in the database
v1.app.DB.Table(tableName).Where(fieldName+" = ?", name).Order("id DESC").First(&result)

// if the name cannot be found then set the status to 404
if len(result) == 0 {
httpStatus = http.StatusNotFound
}
}

return result, httpStatus
}

这样做的缺点是我必须传入要查询的数据库表的名称,这是从结果对象中推断出来的。因为我不太可能更换 table ,所以这并没有太大的不便。

我还必须添加 ORDER到链来解决使用 GORM 时的 MSSQL 问题。

所以现在 API 函数看起来像:
func (v1 *ApiV1) getImage(c *gin.Context) {

// call method to retrieve the items from the database
images, httpStatus := v1.retrieve("images", "name", c.Param("name"))

c.JSON(
httpStatus,
images,
)
}

关于go - 是否可以将结构的 slice 作为接口(interface)传递给方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61407070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com