eddycjy / go-gin-example

An example of gin
MIT License
6.84k stars 1.59k forks source link

封装查询方法,动态传入结构体返回对应的数据,数据转换有点问题,请大佬解惑 #64

Closed wleven closed 5 years ago

wleven commented 5 years ago

想封装一个查询方法,传入一个结构体,然后返回对应的数据。但是报错unsupported destination, should be slice or struct,怎么把interface 转成 struct 类型,还是不能这样写 ,应该怎么封装呢

func QueryUser2(c *gin.Context) {
    var user []models.User
    models.QueryUser2(user)
}
func QueryUser2(model interface{}) (interface{}, error) {
        // 这个是可以正常查询的
    //var user []User
    //err := db.Find(&user).Error
    //return user, err

    err := db.Find(&model).Error
    return &model, err
}
eddycjy commented 5 years ago

@wleven 当然不能这么写,参见 gorm 源码,如下:

        ...
    if kind := results.Kind(); kind == reflect.Slice {
        isSlice = true
        resultType = results.Type().Elem()
        results.Set(reflect.MakeSlice(results.Type(), 0, 0))

        if resultType.Kind() == reflect.Ptr {
            isPtr = true
            resultType = resultType.Elem()
        }
    } else if kind != reflect.Struct {
        scope.Err(errors.New("unsupported destination, should be slice or struct"))
        return
    }

主要是因为如果你赋 interface 会对 ORM 转换带来一系列的麻烦,如果你真的想要用 interface 入参的话,建议你再加一个转换函数,最终返回给 db.Find 的应该是一个具体的 struct 或 slice 即可。