【问题标题】:Cannot use args (type []string) as type []interface {} [duplicate]不能使用 args (type []string) 作为 type []interface {} [重复]
【发布时间】:2020-01-12 01:49:48
【问题描述】:

我的 golang sqlite 插入函数。我正在使用这个包"github.com/mattn/go-sqlite3"

func Insert(args ...string)(err error){
  db, err:=sql.Open("sqlite3","sqlite.db")
  if err !=nil {
    return
  }
  q, err := db.Prepare(args[0])
  if err !=nil{
    return
  }
  _,err = q.Exec(args[1:]...)
  return
 }
main (){
  err := Insert("INSERT INTO table(first,last) VALUES(?,?)","Nantha","nk")
  if err !=nil{
  fmt.Println(err.Error())
    return
  }
}

我收到了这个错误

不能在参数中使用 args (type []string) 作为 type []interface {} q.执行

【问题讨论】:

  • 您必须先将[]string 转换为[]interface{},然后再将其传递给Exec。这样做的方法是遍历字符串并将每个字符串添加到新的 interface{} 切片中。
  • 任何其他不使用循环的解决方案
  • 不,没有。
  • @mkopriva 他可以使用形式上不是循环的递归解决方案;-)

标签: go


【解决方案1】:

错误很明显,该函数需要[]interface{} 类型,但您传入的是[]string 类型的值。您必须先将[]string 转换为[]interface{},然后再将其传递给Exec。这样做的方法是遍历字符串并将每个字符串添加到interface{} 的新切片中。

https://golang.org/doc/faq#convert_slice_of_interface


作为替代方法,您可以更改 Insert 参数类型。

func Insert(query string, args ...interface{}) (err error) {
    db, err := sql.Open("sqlite3", "sqlite.db")
    if err != nil {
        return err
    }
    q, err := db.Prepare(query)
    if err != nil {
        return err
    }
    _, err = q.Exec(args...)
    return err
}

func main() {
    err := Insert("INSERT INTO table(first,last) VALUES(?,?)", "Nantha", "nk")
    if err !=nil{
        fmt.Println(err.Error())
        return
    }
}

请注意,您错误地使用了 database/sql 包。从该包的函数/方法返回的许多对象都需要关闭以释放底层资源。

对于Open返回的*sql.DBPrepare返回的*sql.StmtQuery返回的*sql.Rows等都是如此。

所以你的函数应该看起来更像这样:

func Insert(query string, args ...interface{}) (err error) {
    db, err := sql.Open("sqlite3", "sqlite.db")
    if err != nil {
        return err
    }
    defer db.Close()

    q, err := db.Prepare(query)
    if err != nil {
        return err
    }
    defer q.Close()

    _, err = q.Exec(args...)
    return err
}

还要注意sql.DB 是可重复使用的,这意味着您不必每次需要与数据库通信时都sql.Open 一个新实例。

来自 Open 上的文档:

返回的数据库对于多个 goroutine 并发使用是安全的,并且 维护自己的空闲连接池。因此,打开功能 应该只调用一次。很少需要关闭数据库。

如果您继续按照您的方式进行操作,每次调用 Insert 或任何其他需要与 DB 对话的函数时都打开一个新的 DB,那么您的程序将比如果你有一个 DB 并让你的函数重用它。

【讨论】:

  • v:= []interface{}{"nantha","nk"} -> Insert(q,v) 我得到了不受支持的类型 []interface {},一个接口
  • @Nantha 你不需要这样做,Insert(q, "Nantha", "nk") 仍然可以工作,即使你将Insert 更改为Insert(query string, args ...interface{})
  • @Nantha 如果你想使用v := []interface{}{"nantha","nk"},你可以这样做Insert(q, v...)
  • 它正在工作 :) 非常感谢
猜你喜欢
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 2013-09-19
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
相关资源
最近更新 更多