donglang2010 2014-07-22 03:10
浏览 44
已采纳

如何在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. 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.

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

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

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)
        }
    }
}
  • 写回答

1条回答 默认 最新

  • dsshsta97935 2014-07-22 03:49
    关注

    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. Note also that the type of the slice needs to match the variadic function definition (so in this case a slice of 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. 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...)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序
  • ¥15 求视频摘要youtube和ovp数据集
  • ¥15 在启动roslaunch时出现如下问题