共享db全局处理程序的麻烦

时间:2015-03-30 19:20:55

标签: go

我的代码如下:

package main

import (
  "database/sql"
  "fmt"
  _ "github.com/mattn/go-sqlite3"
  "log"
)

var db *sql.DB

func main() {
  fmt.Println("Starting test ...")

  db, err := sql.Open("sqlite3", "./data.db")
  checkErr(err)

  err = db.Ping()
  checkErr(err)

  fmt.Println(getNames())
}

func checkErr(err error) {
  if err != nil {
    log.Fatal(err)
  }
}

func getNames() []string {
  query := `select name from places`
  rows, err := db.Query(query)
  checkErr(err)
  defer rows.Close()

  var names []string
  for rows.Next() {
    var name string
    rows.Scan(&name)
    names = append(names, name)
  }

  return names
}

我遇到this question,但这种做法对我不起作用。我正在使用sqlite3进行存储。 我的目标很简单。在所有函数之间共享数据库处理程序。 我在构建和运行时遇到以下错误。

Starting test ...
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x411fc6e]

goroutine 1 [running]:
database/sql.(*DB).conn(0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:634   +0x7ae
database/sql.(*DB).query(0x0, 0x421cb10, 0x17, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:933 +0x43
database/sql.(*DB).Query(0x0, 0x421cb10, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:924 +0xa6
main.getNames(0x0, 0x0, 0x0)
    /Users/kdys/Code/go/src/test/main.go:32 +0x94
main.main()
    /Users/kdys/Code/go/src/test/main.go:21 +0x188

goroutine 5 [chan receive]:
database/sql.(*DB).connectionOpener(0xc20802e000)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:589 +0x4c
created by database/sql.Open
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:452 +0x31c

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

您在db内创建了一个本地main变量。当您致电getNames时,它正在使用全局db,这仍然是零。

使用

var err error
db, err = sql.Open("sqlite3", "./data.db")