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

mar*_*cks -2 go

我试图在Golang Web应用程序中使用mysqlstore后端程序包进行gorilla会话.我正在关注这个例子,我的代码是相同的.代码构建和运行正常,但当我去localhost:8080 /在我的浏览器中我收到此错误

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

这是我的代码:

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)
}
Run Code Online (Sandbox Code Playgroud)

这是完整的错误消息:

2019/02/12 02:46:43 http:panic serving [:: 1]:63119:运行时错误:无效的内存地址或无指针取消引用goroutine 34 [运行]:net/http.(*conn).serve.func1 (0xc000112320)/usr/local/Cellar/go/1.11.5/libexec/src/net/http/server.go:1746 + 0xd0 panic(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.(*Registry).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/test sessions/main.go:12 + 0x61 net/http.HandlerFunc.ServeHTTP(0x133a680,0x13770a0,0xc00013c000,0xc000138000)

<...>

pkm*_*pkm 7

store你创建你的主FUNC没有被分配到全球store.您的处理程序中使用的全局存储仍为零.这是因为:=操作符的工作方式,以及您尝试分配给其他地方声明的var的事实.

你可以

  1. 通过不使用:=var err error在该行上方声明来正确地分配给全局存储,例如
var err error
store, err = mysqlstore.NewMySQLStore(...
Run Code Online (Sandbox Code Playgroud)
  1. 或者我推荐的方式(没有全局变量)是:store在main中初始化main,并通过将处理函数包装在一个闭包中并将商店传递给那个来初始化你的处理程序

例如

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)
}

Run Code Online (Sandbox Code Playgroud)