英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论