简体   繁体   English

如何在Go中构建类型接口的varidics?

[英]How can I build varidics of type interface in Go?

I'm building mysql query dynamically ( due the mysql IN clause) so I need to pass a list of arguments as the sql.Query function requires. 我正在动态构建mysql查询(由于mysql IN子句)所以我需要传递一个参数列表,因为sql.Query函数需要。 Any idea how can do that ? 知道如何做到这一点? I don't really understand how the variadic type works or how I can 'generate' it. 我真的不明白可变参数类型是如何工作的,或者我如何“生成”它。 If I pass a slice the sql complains that there is only one parameter instead of len(in clause params) thus I can only assume that the function sees the slice as a parameter instead a list ( variadic ) of parameters. 如果我传递一个切片,那么sql会抱怨只有一个参数而不是len(in clause params)因此我只能假设该函数将切片视为参数而不是参数的列表(可变参数)。

My query / code 我的查询/代码

var carsa []string
q := `SELECT field1,field2 FROM cooltable WHERE nicecars IN(?` + strings.Repeat(",?", len(ha.cars)-1) + ")"
hs := strings.Join(carsa, "','")
    hs = "'" + hs + "'"

    rows, err := cx.Query(q, country, hs)

sql Query sql查询

func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {

Edit: The actual code I'm trying to run fails with error sql: converting Exec argument #0's type: unsupported type []interface {}, a slice 编辑:我正在尝试运行的实际代码失败,错误sql: converting Exec argument #0's type: unsupported type []interface {}, a slice

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

func main() {

    argsS := []string{"apple", "greph", "3rd"}

    db, err := sql.Open("mysql", dbUser+":"+dbPass+"@tcp("+dbHost+":3306)/"+dbName)
    if err != nil {
        return
    }
    query := `SELECT id,label FROM fruits WHERE country=? AND stack IN(?` + strings.Repeat(",?", len(args)-1) + ")"

    args := make([]interface{}, len(ha))
    args["country"] = interface{}("France")

    for i, v := range query {
        args[i] = interface{}(v)
    }

    rows, err := db.Query(q, args...)
    if err != nil {
        return
    }
    var id, label string

    for rows.Next() {
        if err = rows.Scan(&id, label); err != nil {
            fmt.Printf("%v", err)
        }
    }
}

With the given function, you can call it with a variable argument list as: 使用给定的函数,您可以使用变量参数列表调用它:

var query string
var args []interface{}
// initialise variables
cx.Query(query, args...)

This is equivalent to calling Query with each of the elements in the args slice passed as separate arguments, as described in the language specification . 这相当于调用Queryargs slice中的每个元素作为单独的参数传递, 如语言规范中所述 Note also that the type of the slice needs to match the variadic function definition (so in this case a slice of interface{} . 另请注意,切片的类型需要与可变参数函数定义匹配(因此在本例中为interface{}的切片。

Note also that the slice needs to represent the entire variadic argument list. 另请注意,切片需要表示整个可变参数列表。 So it would be an error to call cx.Query(q, country, hs...) , for example. 因此,例如,调用cx.Query(q, country, hs...)会出错。 In cases like that, you will need to construct a slice that holds all the arguments you want to pass. 在这种情况下,您需要构造一个包含您想要传递的所有参数的切片。


Following on from the question's update, to combine the fixed arguments with your variable ones you want your code to look something like this: 继问题的更新之后,要将固定参数与变量参数结合起来,您希望代码看起来像这样:

stacks := []string{"apple", "greph", "3rd"}

query := `SELECT id,label FROM fruits WHERE country=? AND stack IN(?` + strings.Repeat(",?", len(stacks)-1) + ")"

args := make([]interface{}, len(stacks)+1)
args[0] = "France"
for i := range stacks {
    args[i+1] = stacks[i]
}

rows, err := cx.Query(query, args...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM