dongshun7312 2019-02-11 19:59
浏览 47
已采纳

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

This question already has an answer here:

I am trying to use the mysqlstore backend package for gorilla sessions in a Golang web application. I am following this example and my code is identical. The code builds and runs fine but when I go to localhost:8080/ in my browser I am getting this error

runtime error: invalid memory address or nil pointer dereference

Here is my code:

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

Here is the full error message:

2019/02/12 02:46:43 http: panic serving [::1]:63119: runtime error: invalid memory address or nil pointer dereference goroutine 34 /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/testsessions/main.go:12 +0x61 net/http.HandlerFunc.ServeHTTP(0x133a680, 0x13770a0, 0xc00013c000, 0xc000138000)

<…>

</div>
  • 写回答

1条回答 默认 最新

  • dpg98445 2019-02-11 20:13
    关注

    the store that you are creating in your main func is not being assigned to the global store. The global store being used in your handler is still nil. This is because of how the := operator works, and the fact that you are trying to assign to a var declared elsewhere.

    You could either

    1. assign to the global store correctly by not using the := and declaring var err error above that line e.g.
    var err error
    store, err = mysqlstore.NewMySQLStore(...
    
    1. Or the way that i recommend (without global vars) is to: initialize store in main as you have done, and also initialize your handler by wrapping the handler function in a closure and passing the store into that

    e.g.

    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
    ", 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)
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?