你如何传递一片 *interface{} 作为参数?

Scan()我想在 package 中使用sql,但列数以及参数的数量将在运行时发生变化。这是以下人的签名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()?


茅侃侃
浏览 122回答 2
2回答

慕的地8271018

首先,您不能使用[]*interface{}指针切片来接口,而不是[]interface{}接口是指针的地方。[]*interface{}不同于[]interface{}. 只需创建一片接口,其中每个元素都是指向具体类型的指针。这是您将如何执行此操作的片段。var x intvar s stringdata := []interface{}{&x, &s}rows.Scan(data...)关于使用...扩展运算符的注意事项。

红糖糍粑

如果你真的想传递 a []*interface{}(也许你不知道输出的具体类型),你必须首先将每个包装*interface{}在 a 中interface{}:values := make([]interface{}, columnsCount)for i := range values {    values[i] = new(interface{})}传递给...interface{}参数的单个值会自动包装在 a 中interface{},但就像[]int...不会满足一样...interface{},也不会[]*interface{}...。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go