package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
w.Write([]byte("hello world"))
})
http.ListenAndServe(":8000", nil)
}
如果我删除*
中的http.Request
:
github.com/creating_web_app_go/main.go:8:不能在http的参数中使用func文字(类型为func(http.ResponseWriter,http.Request))作为类型func(http.ResponseWriter,* http.Request)。 HandleFunc
我对Go和指针都很陌生。
所以问题是,
为什么http.Request
必须是指针而不是func literal
?任何人都可以用最简单的方式解释这一点,或许可以参考源代码吗?
答案 0 :(得分:8)
因为它是一个大结构。复制它会很昂贵。所以它是一个结构的指针,当结构很大时,它在Go中很常见。它也有一些状态,所以如果被复制它可能会令人困惑。成为一个真实的文字是没有意义的;我不明白为什么会这样做。
答案 1 :(得分:2)
因为这是函数的工作原理。它们有参数,当你调用它们时,你必须提供所需的参数。类型也必须相同。
我认为你真的在问;为什么这样设计?
因为您在向根http.HandleFunc
发出请求时要为"/"
提供委托。在大多数情况下,当RESTful API处理请求时,它需要知道请求中的信息,例如标题,查询参数和/或帖子正文......如果您不想使用该信息,不必,将引用传递给函数的开销并不大。但对于几乎所有实际用例,都需要数据,因此它包含在内,因此它在您提供的委托中成为一个参数。从实现的角度来看,他们需要知道您提供的方法签名是什么,以便他们可以调用它。
因此,为了澄清,您正在查看的内容是func
所需的签名,作为http.HandleFunc
的第二个参数。第一个参数是路径。当对提供的路径发出http请求时,它会调用该方法。该代码将调用该参数调用它handler
并且它需要一致的定义,以便它可以执行handler(resp, req)
而不必进行反射或切换或其他一些控制流只是为了调用你的代码。