英文:
Learning Go: How to use http.HandlerFunc?
问题
尝试学习Go语言
我的测试项目
我正在构建一个与轻量级SQL数据库通信的简单API。我创建了这个函数,用于从数据库表中获取所有主机。根据我的理解,我的函数应该接受一个指向数据库的指针,并返回一个http.HandlerFunc。
func (h HostController) GetAllHosts(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 函数体代码
}
}
到目前为止,一切都应该没问题,但是我不知道如何在main.go中实现它。
目录结构如下:
.
├── controllers
│ └── hostcontroller.go
│
└── main.go
以下是我在main.go中尝试实现的方式:
package main
import (
"examProg/config"
"examProg/controllers"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db := config.GetDB() // 建立与数据库的连接
router := mux.NewRouter()
router.Handle("/host", controllers.HostController.GetAllHosts(db))
fmt.Println("Server is running at port: 2030")
log.Println("Server Running OK | Port: 2030")
log.Fatal(http.ListenAndServe(":2030", router))
}
我不明白如何实现http.HandlerFunc。
英文:
Trying To Learn Go
My Test Project
I am building a simple API to communicate with a light SQL database.
I created this function, that gets all hosts from the DB table.
As I understand, my function should take a pointer to the DB and return me http.HandlerFunc.
func (h HostController) GetAllHosts(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var host entities.Host
var hosts []entities.Host
var errorMessage entities.Error
rows, err := db.Query("SELECT * FROM hosts WHERE hosts = ?", host)
if err != nil {
errorMessage.Message = "Error: Get all hosts"
utils.SendError(w, http.StatusInternalServerError, errorMessage)
return
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&host.ID, &host.Uuid, &host.Name, &host.IPAddress)
if err != nil {
errorMessage.Message = "Error: (Get all hosts) Can't scan rows"
utils.SendError(w, http.StatusInternalServerError, errorMessage)
return
}
hosts = append(hosts, host)
}
////If hosts slice is empty -> no data in database
if len(hosts) == 0 {
errorMessage.Message = "No found hosts in database"
utils.SendError(w, http.StatusInternalServerError, errorMessage)
return
}
//Convert containers content to JSON representation
w.Header().Set("Content-Type", "application/json")
utils.SendSuccess(w, hosts)
}
}
Now, Until here everything should be good, but I don't know how to implement this on main.go
build layout:
.
├── controllers
│ └── hostcontroller.go
│
└── main.go
and this is how I am trying to implement it on the main.go
package main
import (
"examProg/config"
"examProg/controllers"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db := config.GetDB() //Establishing connection to DBase
{
router := mux.NewRouter()
router.Handle("/host", controllers.HostController.GetAllHosts(db))
fmt.Println("Server is running at port: 2030")
log.Println("Server Running OK | Port: 2030")
log.Fatal(http.ListenAndServe(":2030", router))
}
}
I don't understand how to implement the http.HandlerFunc 🙃
答案1
得分: 1
表达式controllers.HostController.GetAllHosts是一个方法表达式。方法表达式的结果是一个函数,除了方法的参数之外,还将接收者类型的实例作为其第一个参数。
因此会出现“调用中参数不足”的错误。
举个例子:
f := controllers.HostController.GetAllHosts
fmt.Println(reflect.TypeOf(f))
// 输出:func(controllers.HostController, *sql.DB)
所以,为了使代码编译通过,你需要将controllers.HostController的实例传递给调用,即:
controllers.HostController.GetAllHosts(controllers.HostController{}, db)
正如你所见,这并不美观。方法表达式肯定有其用途,但我并没有经常遇到它们。我经常看到的是使用方法值。
h := controllers.HostController{}
router.Handle("/host", h.GetAllHosts(db))
英文:
The expression controllers.HostController.GetAllHosts is a method expression. The result of a method expression is a function that, in addition to the method's argument's, takes an instance of the receiver's type as its first argument.
Hence the "not enough arguments in call ..." error.
To illustrate:
f := controllers.HostController.GetAllHosts
fmt.Println(reflect.TypeOf(f))
// output: func(controllers.HostController, *sql.DB)
So, to make the code compile, you need to pass an instance of controllers.HostController to the call, i.e.
controllers.HostController.GetAllHosts(controllers.HostController{}, db)
As you can see, it ain't pretty. Method expressions have their use, I'm sure, but I haven't encountered them much. What I see most often instead, is the use of method values.
h := controllers.HostController{}
router.Handle("/host", h.GetAllHosts(db))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论