运行时错误:再次无效的内存地址或nil指针取消引用

时间:2019-02-11 19:59:55

标签: go

我正在尝试将mysqlstore后端软件包用于Golang Web应用程序中的大猩猩会话。我正在关注this example,并且我的代码是相同的。代码可以构建并正常运行,但是当我在浏览器中访问localhost:8080 /时,出现此错误

  

运行时错误:无效的内存地址或nil指针取消引用

这是我的代码:

package main

  import (
    "fmt"
    "github.com/srinathgs/mysqlstore"
    "net/http"
  )

  var store *mysqlstore.MySQLStore

  func sessTest(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, "foobar")
    session.Values["bar"] = "baz"
    session.Values["baz"] = "foo"
    err = session.Save(r, w)
    fmt.Printf("%#v\n", session)
    fmt.Println(err)
  }

func main() {

    store, err := mysqlstore.NewMySQLStore("root:mypass@tcp(127.0.0.1:3306)/mydb?parseTime=true&loc=Local", "sessions", "/", 3600, []byte("<SecretKey>"))
    if err != nil {
      panic(err)
    }
    defer store.Close()

        http.HandleFunc("/", sessTest)
        http.ListenAndServe(":8080", nil)
}

这是完整的错误消息:

  

2019/02/12 02:46:43 http:紧急服务[:: 1]:63119:运行时错误:   无效的内存地址或nil指针取消引用goroutine 34   [运行中]:net / http。(* conn).serve.func1(0xc000112320)     /usr/local/Cellar/go/1.11.5/libexec/src/net/http/server.go:1746 + 0xd0   紧急(0x12c9f40,0x1560950)     /usr/local/Cellar/go/1.11.5/libexec/src/runtime/panic.go:513 + 0x1b9   github.com/srinathgs/mysqlstore.(*MySQLStore).New(0x0,0xc000138000,   0x1324045、0x6、0x158afa0、0xc00010a000、0xb)     /Users/Mark/go/src/github.com/srinathgs/mysqlstore/mysqlstore.go:137   + 0xef github.com/gorilla/sessions.(*注册表).Get(0xc00011e0e0,0x1376e20,0x0,0x1324045,0x6,0xc00010c100,0x0,0x1)     /Users/Mark/go/src/github.com/gorilla/sessions/sessions.go:139 + 0x142   github.com/srinathgs/mysqlstore.(*MySQLStore).Get(0x0,0xc000138000,   0x1324045、0x6、0x1086222、0xc00010a044、0xc00010a050)     /Users/Mark/go/src/github.com/srinathgs/mysqlstore/mysqlstore.go:131   + 0x63 main.sessTest(0x13770a0,0xc00013c000,0xc000138000)/Users/Mark/go/src/testsessions/main.go:12 + 0x61   净/http.HandlerFunc.ServeHTTP(0x133a680、0x13770a0、0xc00013c000,   0xc000138000)

     

<...>

1 个答案:

答案 0 :(得分:5)

您在主功能中创建的store未分配给全局store。处理程序中使用的全局存储仍然为零。这是因为:=运算符的工作原理,以及您试图分配给在其他地方声明的var的事实。

您可以

  1. 通过不使用:=并在该行上方声明var err error来正确分配给全局存储 例如
var err error
store, err = mysqlstore.NewMySQLStore(...
  1. 或者我建议的方式(没有全局变量)是:像这样在main中初始化store,并通过将处理程序函数包装在闭包中并将存储传递到该存储中来初始化处理程序< / li>

例如

package main

import (
    "fmt"
    "github.com/srinathgs/mysqlstore"
    "net/http"
)

// note: this returns a http.HandlerFunc, which works because
// http.HandlerFunc is just a named type for a function which accepts http.ResponseWriter and *http.Request as args
// see the docs at https://golang.org/pkg/net/http/#HandlerFunc
// (but yea at the end of the day, this is a function which returns another function)
func makeSessTest(store *mysqlstore.MySQLStore) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        session, err := store.Get(r, "foobar")
        session.Values["bar"] = "baz"
        session.Values["baz"] = "foo"
        err = session.Save(r, w)
        fmt.Printf("%#v\n", session)
        fmt.Println(err)
    }
}

func main() {
    store, err := mysqlstore.NewMySQLStore("root:mypass@tcp(127.0.0.1:3306)/mydb?parseTime=true&loc=Local", "sessions", "/", 3600, []byte("<SecretKey>"))
    if err != nil {
        panic(err)
    }
    defer store.Close()

    http.HandleFunc("/", makeSessTest(store))
    http.ListenAndServe(":8080", nil)
}