如何将类型传递给http处理程序

huangapple go评论86阅读模式
英文:

How to pass type into an http handler

问题

我正在尝试将我的http go代码分离成“控制器”,通过创建一个新的包来实现,但是无法弄清楚如何将db类型传递给处理程序。我希望能够将我在main.go中创建的Db类型传递给index.go中的Index处理程序。如果这种解决方法是错误的,请告诉我更好的方法(我正在学习并希望保持简单)。到目前为止,我的代码如下:

main.go:

package main

import (

    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "log"
    "mvc3/app/c"
    "net/http"
)

var Db *sql.DB

func main() {

    fmt.Println("Starting up!")

    var err error
    Db, err = sql.Open("mysql", "root@/dev?charset=utf8")
    if err != nil {
        log.Fatalf("Error on initializing database connection: %s", err.Error())
    }

    Db.SetMaxIdleConns(100)

    err = Db.Ping()
    if err != nil {
        log.Fatalf("Error on opening database connection: %s", err.Error())
    }

    r := mux.NewRouter()
    r.HandleFunc("/", c.Index)

    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

/app/c/index.go:

package c

import (
    "fmt"
    "net/http"
)

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

    fmt.Fprintf(w, "Hello world!")

}
英文:

I'm attempting to separate my http go code into "controllers" by creating a new package for them, but can't figure out how to pass a db type into the handler. I want to be able to pass in the Db type that I create in main.go into my Index handler in index.go. If this is the wrong way to solve this, let me know a better way (I'm learning as I go and would like to keep it simple for now). My code so far:

main.go:

package main

import (

    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "log"
    "mvc3/app/c"
    "net/http"
)

var Db *sql.DB

func main() {

    fmt.Println("Starting up!")

    var err error
    Db, err = sql.Open("mysql", "root@/dev?charset=utf8")
    if err != nil {
    	log.Fatalf("Error on initializing database connection: %s", err.Error())
    }

    Db.SetMaxIdleConns(100)

    err = Db.Ping()
    if err != nil {
	    log.Fatalf("Error on opening database connection: %s", err.Error())
     }

     r := mux.NewRouter()
     r.HandleFunc("/", c.Index)

    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

/app/c/index.go:

package c

import (
    "fmt"
    "net/http"
)

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

    fmt.Fprintf(w, "Hello world!")

}

Thanks!

答案1

得分: 11

使用闭包。

在app/c中将Index更改为:

func Index(db *sql.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 在这里使用db进行操作
        fmt.Fprintf(w, "Hello world!")
    }
}

然后在你的main函数中这样使用:r.HandleFunc("/", c.Index(db))

Index函数返回一个匿名函数,该函数符合HandleFunc类型,并且闭包了传入的db值,使得你的处理程序可以访问该变量。

英文:

use a closure.

in app/c change Index to:

func Index(db *sql.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // do stuff with db here
        fmt.Fprintf(w, "Hello world!")
    }
}

then in your main function use it like so: r.HandleFunc("/", c.Index(db))

The Index function returns an anonymous function that fits the the HandleFunc type and also closes over the value of the db that was passed in giving your handler access to that variable.

huangapple
  • 本文由 发表于 2013年7月22日 10:51:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/17779204.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定