gpt4 book ai didi

go - 填充作为参数给出的接口(interface)类型的一部分(例如,为数据库/sql 实现 ScanAll)

转载 作者:数据小太阳 更新时间:2023-10-29 03:10:19 27 4
gpt4 key购买 nike

我们如何实现一个函数,该函数将返回 SQL 查询产生的所有行并将它们转换为 dest 这是一个接口(interface)数组(可能无法像 Scan 一样工作) ?

我假设目标数组必须作为函数的参数给出。但是,我仍然不知道我应该如何完成实现:

func GetAll(query string, dest interface{}) error {

rows, err := s.db.Query(query)
if err != nil {
return err
}
defer rows.Close()

for rows.Next() {
var destRow ??? /* do not have a type. using reflect.TypeOf(dest).Elem()? */
err := rows.Scan(&destRow)
if err != nil {
return err
}
dest = append(dest, destRow) /* would even compile? */
}
return nil
}

它看起来与 json.Unmarshal 实际上必须做的事情没有太大区别......

最佳答案

这是一个使用 reflect package 的解决方案.使用指向 slice 的指针调用函数。

func GetAll(query string, dest interface{}) error {

// Return error if dest is not a pointer to a slice.
slice := reflect.ValueOf(dest)
if slice.Kind() != reflect.Ptr {
return errors.New("dest must be pointer")
}
slice = slice.Elem()
if slice.Kind() != reflect.Slice {
return errors.New("dest must be pointer to struct")
}

rows, err := db.Query(query)
if err != nil {
return err
}
defer rows.Close()

for rows.Next() {
// Create a new slice element. The variable elementp holds a
// pointer to the new element.
elementp := reflect.New(slice.Type().Elem())

err := rows.Scan(elementp.Interface())
if err != nil {
return err
}

// Append the element to the slice.
slice.Set(reflect.Append(slice, elementp.Elem()))
}
return nil
}

当查询结果只有一列并且 dest 是指向适合该列的类型的 slice 时,上述代码适用于标准数据库/sql 包。这是一个例子:

var names []string
if err := GetAll(db, "select name from people", &names); err != nil {
// handle error
}

此代码还应与支持将多列扫描到结构的数据库包一起使用。

关于go - 填充作为参数给出的接口(interface)类型的一部分(例如,为数据库/sql 实现 ScanAll),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53159944/

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