我正在嘗試使用檔案資料庫 bbolt 作為鍵/值存盤。下面是我的代碼
package handler
import (
"encoding/json"
"log"
"net/http"
"os"
"go.etcd.io/bbolt"
bolt "go.etcd.io/bbolt"
yml "gopkg.in/yaml.v3"
)
type urlDB struct {
db *bbolt.DB
}
func (u urlDB) ensureDB() {
u.db, _ = bolt.Open("url.db", 0600, nil)
}
func MapHandler(pathsToURLs map[string]string, fallback http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if _, ok := pathsToURLs[path]; ok {
http.Redirect(w, r, pathsToURLs[path], http.StatusFound)
} else {
fallback.ServeHTTP(w, r)
}
}
}
func DefaultMap(fallback http.Handler) http.HandlerFunc {
db := urlDB{}
db.ensureDB()
//bkt := db.db.createBucket()
//createSampleData(bkt)
defer db.db.Close()
bktName := "URLBucket"
createBucket(db.db, bktName)
addSampleData(db.db, bktName, "/gm", "https://mail.google.com")
addSampleData(db.db, bktName, "/ym", "https://mail.yahoo.com")
pathToURLs := make(map[string]string)
getData(db.db, bktName, pathToURLs)
return MapHandler(pathToURLs, fallback)
}
func createBucket(db *bbolt.DB, bktName string) {
db.Update(func(tx *bbolt.Tx) error {
_, _ = tx.CreateBucketIfNotExists([]byte(bktName))
return nil
})
}
func addSampleData(db *bbolt.DB, bktName, key, value string) {
db.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte(bktName))
_ = b.Put([]byte(key), []byte(value))
return nil
})
}
func getData(db *bbolt.DB, bktName string, pathToURLs map[string]string) {
db.View(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte(bktName))
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
pathToURLs[string(k)] = string(v)
}
return nil
})
}
因此,在handler:DefaultMap使用以下代碼從 main.go呼叫它時
mux := http.NewServeMux()
var urlHandler http.HandlerFunc
urlHandler = handler.DefaultMap(mux)
http.ListenAndServe(":8080", urlHandler)
但我收到如下錯誤
panic: runtime error: invalid memory address or nil pointer dereference
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1b8 pc=0x6126cf]
goroutine 1 [running]:
go.etcd.io/bbolt.(*DB).Close(0x0)
panic({0x686180, 0x8dcb50})
/usr/local/go/src/runtime/panic.go:1038 0x215
go.etcd.io/bbolt.(*DB).beginRWTx(0x0)
/home/xx/coding/go/packages/pkg/mod/go.etcd.io/bbolt@v1.3.6/db.go:634 0x38
go.etcd.io/bbolt.(*DB).Begin(0x0, 0x0)
/home/xx/coding/go/packages/pkg/mod/go.etcd.io/bbolt@v1.3.6/db.go:589 0x1d
go.etcd.io/bbolt.(*DB).Update(0x0, 0xc000187e38)
/home/xx/coding/go/packages/pkg/mod/go.etcd.io/bbolt@v1.3.6/db.go:725 0x3e
github.com/xx/urlshortner/handler.createBucket(0x6c588d, {0x6c6358, 0xc000187ec8})
/home/xx/coding/go/src/urlshortner/handler/handler.go:97 0x48
github.com/xx/urlshortner/handler.DefaultMap({0x7243e0, 0xc00014a300})
/home/xx/coding/go/src/urlshortner/handler/handler.go:88 0x95
main.main()
/home/xx/coding/go/src/urlshortner/main.go:24 0xcc
exit status 2
非常感謝任何幫助。
謝謝你。
uj5u.com熱心網友回復:
這一行:
github.com/xx/urlshortner/handler.createBucket(0x6c588d, {0x6c6358, 0xc000187ec8})
說錯誤在createBucket. 看著createBucket:
db.Update(func(tx *bbolt.Tx) error {
根據堆疊跟蹤,它呼叫Update, 并且db是這里唯一可以為 nil 的東西。
跟蹤回呼,可以看到:
func (u urlDB) ensureDB() {
u.db, _ = bolt.Open("url.db", 0600, nil)
}
因此,db open 失敗,并且u.db為零。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/457418.html
標籤:走
