我想Scan()在 package 中使用sql,但列数以及参数数将在运行时发生变化。这是签名Scan():
func (rs *Rows) Scan(dest ...interface{}) error
Run Code Online (Sandbox Code Playgroud)
根据文档,*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())
}
}
}
Run Code Online (Sandbox Code Playgroud)
编译失败,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())
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我不能使用它,因为在编译时列数是未知的。如何编写此代码以便可以将可变数量的*interface{}to传递给rows.Scan()?
首先,您不能使用[]*interface{}指向接口的指针切片,而不是[]interface{}接口是指针的位置。[]*interface{}不同于[]interface{}. 只需创建一个接口片段,其中每个元素都是一个指向具体类型的指针。
这是您将如何执行此操作的片段。
var x int
var s string
data := []interface{}{&x, &s}
rows.Scan(data...)
Run Code Online (Sandbox Code Playgroud)
关于使用...扩展运算符的注意事项。
以下是一些相关的问题,将进一步解释:
无法将 []string 转换为 []interface {}