我想在软件包sql
中使用Scan()
,但是列数以及参数的数目将在运行时改变。这是Scan()
的签名:
func (rs *Rows) Scan(dest ...interface{}) error
根据文档,*interface{}
是Scan()
接受的类型之一。因此,我想创建一个[]*interface{}
的切片,并将其作为参数扩展。
这是我认为可行的方法:
func query(database *sql.DB) {
rows, _ := database.Query("select * from testTable")
for rows.Next() {
data := make([]*interface{}, 2)
err := rows.Scan(data...) // Compilation error
fmt.Printf("%v%v\n", *data[0], *data[1])
if err != nil {
fmt.Println(err.Error())
}
}
}
编译失败,cannot use data (type []*interface {}) as type []interface {} in argument to rows.Scan
。我认为data...
会扩展为&data[0], &data[1]
,但显然不会。我不明白该错误信息。 *interface{}
与interface{}
兼容,所以为什么不能扩展指向接口类型的指针?
这有效:
func query(database *sql.DB) {
rows, _ := database.Query("select * from testTable")
for rows.Next() {
data := make([]*interface{}, 2)
err := rows.Scan(&data[0], &data[1]) // Only changed this line
fmt.Printf("%v%v\n", *data[0], *data[1]) // Outputs "[48][116 101 120 116]"
if err != nil {
fmt.Println(err.Error())
}
}
}
但是我不能使用它,因为在编译时列数是未知的。如何编写此代码,以便可以将可变数量的*interface{}
传递给rows.Scan()
?
答案 0 :(得分:3)
首先,在接口是指针的情况下,切勿使用[]*interface{}
指针的切片来接口,而不能使用[]interface{}
。 []*interface{}
与[]interface{}
不同。只需创建一片接口,其中每个元素都是指向具体类型的指针。
以下是您如何执行此操作的摘要。
var x int
var s string
data := []interface{}{&x, &s}
rows.Scan(data...)
请注意使用...
扩展运算符。
以下是一些相关的问题,这些问题将进一步解释:
golang: slice of struct != slice of interface it implements?