通过反射调用 Scan() 变量函数
Rows.Scan() 函数提供了一种从数据库检索数据的便捷方法询问。然而,它使用可变数量的指针作为其参数,这对于使用反射来合并可能具有挑战性。 考虑以下场景:
您希望使用从查询获得的值动态填充切片并利用 Rows.Scan() 提取数据。在这种情况下,您需要确定列数并创建一个切片来存储值。
常见陷阱:
尝试使用反射来调用Scan() 函数可能会导致意外结果。这是因为 Rows.Scan() 需要指向值的指针,并且简单地传递一个 interface{} 值的切片将导致零引用。
解决方案:
为了通过反射成功调用 Scan(),采用了双切片方法。第一个切片values保存实际数据,第二个切片valuesPtrs包含指向values中每个元素的指针。
对于查询结果中的每一列,valuesPtrs中的指针映射到相应的元素在价值观中。随后,可以使用valuesPtrs作为参数来调用Rows.Scan(),从而有效地填充值。
工作示例:
package main import ( "fmt" _ "github.com/lib/pq" "database/sql" ) func main() { db, _ := sql.Open( "postgres", "user=postgres dbname=go_testing password=pass sslmode=disable") rows, _ := db.Query("SELECT * FROM _user;") columns, _ := rows.Columns() count := len(columns) values := make([]interface{}, count) valuesPtrs := make([]interface{}, count) for rows.Next() { for i := range columns { valuesPtrs[i] = &values[i] } rows.Scan(valuesPtrs...) for i, col := range columns { val := values[i] b, ok := val.([]byte) var v interface{} if (ok) { v = string(b) } else { v = val } fmt.Println(col, v) } } }
在此示例中,rows.Scan()。 Scan() 使用指针切片 valuePtrs 调用,用检索到的数据填充值切片。然后循环打印每个列名称及其相应的值。
以上是如何使用反射调用数据库/SQL Rows.Scan() 可变参数函数?的详细内容。更多信息请关注PHP中文网其他相关文章!