使用sqlx封装通用FindAll查询报错expected slice but got interface解决方法
问题原因
你遇到的报错是因为参数传递和内部取址逻辑不符合sqlx的Select方法要求:
- sqlx的
Select方法第一个参数必须是切片的指针,才能将查询结果写入对应切片 - 原代码中你对
interface{}类型的model取地址,得到的是*interface{}类型,sqlx无法识别为切片指针 - 调用时传入的是切片值而非指针,就算函数逻辑正确也无法将结果回写到原切片变量
修改方案
1. 调整FindAll函数逻辑
去掉函数内部对model的取址操作,直接透传给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 }
2. 调整调用方式
调用时传入切片的指针而非切片值:
albums := []Album{} err := database.FindAll(&albums, "album", a.DB)
可选优化:增加参数类型校验
可以通过反射提前校验入参合法性,避免运行时出现难以定位的错误:
import "reflect" func FindAll(model interface{}, table string, db *sqlx.DB) error { // 校验入参必须是切片指针 v := reflect.ValueOf(model) if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Slice { return fmt.Errorf("FindAll: 第一个参数必须为切片指针类型") } err := db.Select(model, "SELECT * FROM "+table) if err != nil { return fmt.Errorf("FindAll: %v", err) } return nil }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

