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