我正在寻找使用反射来调用
Rows.Scan()功能。然而,它需要一个可变数量的指针,但我是新来的戈兰,没有很多源代码示例。我需要使用反思,因为我打算使用Query调用的值填充一个切片。所以基本上使用rows.Columns()获取行的长度,然后make()一个[] interface {}的片段填充通常使用传递给Scan()函数的指针来填充的数据点。
基本上这样的代码:
- col := rows.Columns()
- vals := make([]interface{},len(cols))
- rows.Scan(&vals)
任何人都有一个例子,调用一个可以使用反射的指针的可变函数,我可以看一下?
编辑:
示例代码似乎没有做我以后的事情。
- package main
- import (
- _ "github.com/lib/pq"
- "database/sql"
- "fmt"
- )
- func main() {
- db,_ := sql.Open(
- "postgres","user=postgres dbname=Go_Testing password=ssap sslmode=disable")
- rows,_ := db.Query("SELECT * FROM _users;")
- cols,_ := rows.Columns()
- for rows.Next() {
- data := make([]interface{},len(cols))
- rows.Scan(data...)
- fmt.Println(data)
- }
- }
结果:
- [<nil> <nil> <nil> <nil> <nil>]
- [<nil> <nil> <nil> <nil> <nil>]
- [<nil> <nil> <nil> <nil> <nil>]
- [<nil> <nil> <nil> <nil> <nil>]
- [<nil> <nil> <nil> <nil> <nil>]
- [<nil> <nil> <nil> <nil> <nil>]
解决方法
这是我到达的解决方案。它在遍历数据之前没有得到类型,所以在通过Scan()方法拉出值之前,手头不知道每个值的类型,但是实际上并不需要先了解类型。
诀窍是创建2个片段,一个用于值,一个保存与值片段并行的指针。然后一旦指针用于填充数据,则值数组实际上用数据填充,然后可以用它来填充其他数据结构。
- package main
- import (
- "fmt"
- _ "github.com/lib/pq"
- "database/sql"
- )
- func main() {
- db,"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)
- valuePtrs := make([]interface{},count)
- for rows.Next() {
- for i,_ := range columns {
- valuePtrs[i] = &values[i]
- }
- rows.Scan(valuePtrs...)
- for i,col := range columns {
- var v interface{}
- val := values[i]
- b,ok := val.([]byte)
- if (ok) {
- v = string(b)
- } else {
- v = val
- }
- fmt.Println(col,v)
- }
- }
- }