title: Package-wide variable assignment in Golang's init() function
body: <p>I want to initialize a package-wide variable in some Go code to connect to a database, but I keep getting a nil pointer exception, so clearly the assignment isn't occurring properly. This throws an error:</p>
  
  <pre><code>package main
  
  import (
  "fmt"
  "database/sql"
  
  _ "github.com/lib/pq"
  )
  
  var connection *sql.DB
  
  func init() {
      connectionString := "host=172.17.0.3 dbname=postgres user=postgres password=postgres port=5432 sslmode=disable"
  
      connection, err := sql.Open(
          "postgres",
          connectionString,
      )
      check(err)
  
      err = connection.Ping()
      check(err)
  }
  
  func main() {
      TestConnect()
  }
  
  func TestConnect() {
      var pid int
  
      err := connection.QueryRow("SELECT pg_backend_pid()").Scan(&amp;pid)
      check(err)
      fmt.Printf("pid: %v", pid)
  }
  
  func check(err error) {
      if err != nil {
          panic(err)
      }
  }
  </code></pre>
  
  <p>Here's the error:</p>
  
  <pre><code>panic: runtime error: invalid memory address or nil pointer dereference
  [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4c1a1a]
  
  goroutine 1 [running]:
  database/sql.(*DB).conn(0x0, 0x70b7c0, 0xc4200102b8, 0x1, 0xc420055e08, 0x4c28df, 0xc4200b0000)
      /usr/local/go/src/database/sql/sql.go:896 +0x3a
  database/sql.(*DB).query(0x0, 0x70b7c0, 0xc4200102b8, 0x630335, 0x17, 0x0, 0x0, 0x0, 0x101, 0x741c80, ...)
      /usr/local/go/src/database/sql/sql.go:1245 +0x5b
  database/sql.(*DB).QueryContext(0x0, 0x70b7c0, 0xc4200102b8, 0x630335, 0x17, 0x0, 0x0, 0x0, 0x0, 0x8, ...)
      /usr/local/go/src/database/sql/sql.go:1227 +0xb8
  database/sql.(*DB).QueryRowContext(0x0, 0x70b7c0, 0xc4200102b8, 0x630335, 0x17, 0x0, 0x0, 0x0, 0xc420010cb0)
      /usr/local/go/src/database/sql/sql.go:1317 +0x90
  database/sql.(*DB).QueryRow(0x0, 0x630335, 0x17, 0x0, 0x0, 0x0, 0x0)
      /usr/local/go/src/database/sql/sql.go:1325 +0x7c
  main.TestConnect()
      /home/tom/go/src/go-rest/ignore/connect.go:32 +0x82
  main.main()
      /home/tom/go/src/go-rest/ignore/connect.go:26 +0x20
  exit status 2
  </code></pre>
  
  <p>However, if I switch it up so I can use the <code>=</code> operator on <code>connection</code> instead of <code>:=</code>...</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "database/sql"
  
      _ "github.com/lib/pq"
  )
  
  var connection *sql.DB
  
  func init() {
      connectionString, err := GetConnectionString()
  
      connection, err = sql.Open(
          "postgres",
          connectionString,
      )
      check(err)
  
      err = connection.Ping()
      check(err)
  }
  
  func main() {
      TestConnect()
  }
  
  func TestConnect() {
      var pid int
  
      err := connection.QueryRow("SELECT pg_backend_pid()").Scan(&amp;pid)
      check(err)
      fmt.Printf("pid: %v", pid)
  }
  
  func GetConnectionString() (string, error) {
      return "host=172.17.0.3 dbname=postgres user=postgres password=postgres port=5432 sslmode=disable", nil
  }
  
  func check(err error) {
      if err != nil {
          panic(err)
      }
  }
  </code></pre>
  
  <p>Then everything works as expected, and the variable is properly assigned. Because the <code>err</code> variable is previously undefined, I have to use <code>:=</code> for assignment, but this seems to assume that I'm initializing a function-scoped <code>connection</code> variable, and not trying to assign to the package-scoped <code>connection</code> variable. Is there a way to force this assignment in Go? As it stands, I need to write useless, boilerplate code to get this to work the right way, and it seems like there should be a better way.</p>
  
  <p>Of course, the possibility also stands that I'm trying to do something that I perhaps shouldn't be. Based on my research though, <a href="http://go-database-sql.org/accessing.html" rel="nofollow noreferrer">this guide</a> seems to suggest using a package-wide database connection is better then creating / closing connections as needed.</p>