预期切片但得到界面

Expected slice but got interface

我正在使用 sqlx 包进行数据库查询。我正在尝试为我的数据库包

中的所有模型创建一个全局 SELECT *
func FindAll(model interface{}, table string, db *sqlx.DB) error {
    err := db.Select(&model, "SELECT * FROM "+table)
    if err != nil {
        return fmt.Errorf("FindAll: %v", err)
    }
    return nil
}

我就是这样用的

albums := []Album{}
err := database.FindAll(albums, "album", a.DB)

但是我得到了这个错误:expected slice but got interface

我不知道如何管理第一个模型参数以使其适用于任何模型

FindAll()中,model参数是interface{}类型。您将 []Album 的值传递给它。它已经包装了一个切片值。

db.Select() 还需要一个接口类型的参数(与 interace{} 类型相同)。你有一个正是这种类型的接口值,只需按原样传递它:

err := db.Select(model, "SELECT * FROM "+table)

虽然请注意,为了让 db.Select() 能够修改它,它必须是一个指针,所以 model 应该将指针包装到一个切片,而不是“只是”一个切片。所以这样调用 FindAll()

err := database.FindAll(&albums, "album", a.DB)

当需要接口类型时传递具体类型的值时,它会被包装在接口值中。

当你传递一个接口值时,如果它是相同的接口类型,它将按原样传递。如果它是不同的接口类型,存储在其中的具体值将被包装(重新包装)在预期接口类型的接口值中。

当您传递 &model 时,您传递的是 *interface{} 的值,一个指向接口类型的指针。那不是接口类型,它是具体类型,所以这个具体类型在传递时会被包装在接口值中。

参见相关问题: