猿问

golang http 处理程序上下文

我正在尝试使用以下代码了解 golang 中的变量范围。在此示例中,在 http 中调用页面将回显 uri 查询以及 Boltdb 中存储的值。


问题是数据库驱动程序似乎没有在 http 处理程序上下文中正确运行:它不会向 stdout 或 http 请求打印任何内容。


我期待它打印:


他喜欢 <'uri query content'> 但更喜欢披萨(来自 bolt.db 驱动程序的数据)


如何修复此代码?包主


import (

    "fmt"

    "net/http"

    "log"

    "github.com/boltdb/bolt"

)


var db bolt.DB


func handler(w http.ResponseWriter, r *http.Request) {

    dberr := db.Update(func(tx *bolt.Tx) error {

    log.Println("here")

        b := tx.Bucket([]byte("MyBucket"))

            loving := b.Get([]byte("loving"))

        log.Printf("He's loving %s but prefers %s",r.URL.Path[1:], string(loving))

            fmt.Fprintf(w,"He's loving %s but prefers %s",r.URL.Path[1:], string(loving) )

        return nil

    })

    if dberr != nil {

        fmt.Errorf("db update: %s", dberr)

    }

    log.Printf("Finished handling")

}


func main() {


    db, err := bolt.Open("my.db", 0600, nil)

    if err != nil {

        log.Fatal(err)

    }else{

        log.Println("database opened")

    }

    dberr := db.Update(func(tx *bolt.Tx) error {

        b, err := tx.CreateBucketIfNotExists([]byte("MyBucket"))

        if err != nil {

        return fmt.Errorf("create bucket: %s", err)

        }

        err2 := b.Put([]byte("loving"), []byte("pizza"))

        if err2 != nil {

        return fmt.Errorf("put loving: %s", err2)

        }

        loving := b.Get([]byte("loving"))

        log.Printf("He's loving %s", string(loving))

        return nil

    })


        if dberr != nil {

        fmt.Errorf("db update: %s", err)

        }

    defer db.Close()


    http.HandleFunc("/", handler)

    http.ListenAndServe(":8080", nil)


   }



呼唤远方
浏览 214回答 1
1回答

有只小跳蛙

我想我看到了你的错误。这个通常有点难以跟踪,因为它只是:在等号的前面。这基本上是一个作用域问题,因为您声明db为全局db变量,同时创建了一个作用域为您的主函数的变量。您过去常常db, err := ...分配值,而不仅仅是=. :=将声明和推断类型。由于它也在进行声明,因此db您在main函数中使用的不是db您在全局范围内声明的。同时,处理程序仍在尝试使用db在全局范围内声明的 。下面的代码与您最初使用的代码相同,在代码中添加了一些注释以概述工作更改的内容。希望这可以帮助!package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "log"&nbsp; &nbsp; "net/http"&nbsp; &nbsp; "github.com/boltdb/bolt")var db *bolt.DB // this is going to be a pointer and is going to be nil until its set by the main functionfunc handler(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; dberr := db.Update(func(tx *bolt.Tx) error {&nbsp; &nbsp; &nbsp; &nbsp; log.Println("here")&nbsp; &nbsp; &nbsp; &nbsp; b := tx.Bucket([]byte("MyBucket"))&nbsp; &nbsp; &nbsp; &nbsp; loving := b.Get([]byte("loving"))&nbsp; &nbsp; &nbsp; &nbsp; log.Printf("He's loving %s but prefers %s", r.URL.Path[1:], string(loving))&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(w, "He's loving %s but prefers %s", r.URL.Path[1:], string(loving))&nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; })&nbsp; &nbsp; if dberr != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Errorf("db update: %s", dberr)&nbsp; &nbsp; }&nbsp; &nbsp; log.Printf("Finished handling")}func main() {&nbsp; &nbsp; var err error&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// this will have to be declared because of the next line to assign db the first value returned from `bolt.Open`&nbsp; &nbsp; db, err = bolt.Open("my.db", 0600, nil) // notice that this has changed and is no longer `db, err := ...` rather its `db, err = ...`&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatal(err)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; log.Println("database opened")&nbsp; &nbsp; }&nbsp; &nbsp; dberr := db.Update(func(tx *bolt.Tx) error {&nbsp; &nbsp; &nbsp; &nbsp; b, err := tx.CreateBucketIfNotExists([]byte("MyBucket"))&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("create bucket: %s", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; err2 := b.Put([]byte("loving"), []byte("pizza"))&nbsp; &nbsp; &nbsp; &nbsp; if err2 != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("put loving: %s", err2)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; loving := b.Get([]byte("loving"))&nbsp; &nbsp; &nbsp; &nbsp; log.Printf("He's loving %s", string(loving))&nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; })&nbsp; &nbsp; if dberr != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Errorf("db update: %s", err)&nbsp; &nbsp; }&nbsp; &nbsp; defer db.Close()&nbsp; &nbsp; http.HandleFunc("/", handler)&nbsp; &nbsp; http.ListenAndServe(":3000", nil)}
随时随地看视频慕课网APP

相关分类

Go
我要回答