panic: runtime error問題分享

panic: runtime error: invalid memory address or nil pointer dereference

關於這個錯誤問題panic: runtime error: invalid memory address or nil pointer dereference,我是如何解決的mysql

通常這個問題的出現,從提示上意思意思是無效的內存地址或空指針
我遇到的問題是這樣的我寫了一個Session管理器,其中有一個函數是這樣的sql

// SessionStart 啓動Session功能
func (m *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session Session, err error) {
    m.lock.Lock()
    defer m.lock.Unlock()
    cookie, err := r.Cookie(m.cookieName)

    if err != nil || cookie.Value == "" {
        sid := m.GenerateSID()
        session, err = m.provider.SessionInit(sid)
        if err != nil {
            return nil, err
        }
        newCookie := http.Cookie{
            Name:     m.cookieName,
            Value:    url.QueryEscape(sid),
            Path:     "/",
            HttpOnly: true,
            MaxAge:   int(m.maxLifeTime),
        }
        http.SetCookie(w, &newCookie)
    } else {
        sid, _ := url.QueryUnescape(cookie.Value)
        session, _ = m.provider.SessionRead(sid)
    }

    return
}

而後我在使用的時候,是這樣的cookie

var appSession *session.Manager

// WelcomeLogin 歡迎登陸頁
func WelcomeLogin(w http.ResponseWriter, r *http.Request) {
    _, err := appSession.SessionStart(w, r)
    if err != nil {
        fmt.Println(err)
        return
    }

    cookie, err := r.Cookie("sessionid")
    if err != nil {
        fmt.Fprintf(w, "session")
    }

    fmt.Fprintf(w, cookie.Value)
}

func init() {
    appSession, _ := session.GetManager("memory", "sessionid", 3600)

    go appSession.SessionGC()
}

這段兩端代碼正常編譯是沒有任何問題,可是在調用WelcomeLogin的時候就報錯了,由於WelcomeLogin函數調用了SessionStart,而SessionStart又調用了m.lock.Lock()。
這裏注意m.lock.Lock()中的m,從錯誤提示上看是m的郭,問題在哪裏呢,我經過記錄日誌的方式找到了緣由,其實session

appSession, _ := session.GetManager("memory", "sessionid", 3600)

這段代碼和下面app

appSession, _ = session.GetManager("memory", "sessionid", 3600)

這段代碼是有很大區別的
使用第一段的時候
appSession獲得的值是nil,而使用第二段的代碼的時候就能正常賦值了。ide

這個問題在之後使用init進行操做變量從新賦值的時候必定要注意。爲何我能忽然想到這個問題,由於我以前的幾篇文章是寫如何使用MySQL的,其中有個init中初始化的時候,從新賦值鏈接的變量涉及到這個問題,可是的作法就是直接賦值,並無經過':='的方式賦值函數

// MySQLDB Conn
var MySQLDB *sql.DB

func init() {
    db, err := sql.Open("mysql", "root:123456@/wiki?charset=utf8")
    MySQLDB = db
    checkErr(err)
}
相關文章
相關標籤/搜索