2015-06-30 58 views
2
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为什么必须将http.Request参数作为指针?

github.com/creating_web_app_go/main.go:8:不能使用FUNC字面(类型FUNC(http.ResponseWriter,http.Request))作为类型func(http.ResponseWriter,* http.Request)参数http.HandleFunc

我对Go和指针都很陌生。

所以问题是, 为什么必须http.Request是一个指针,而不是一个func literal?任何人都可以用最简单的方式解释这个,也许可以参考源代码?

+0

为什么-1?这真的是一个很好的问题吗? –

+0

其实这是一个非常好的问题imo – Yar

回答

8

因为它是一个很大的结构。复制它会很昂贵。所以它是一个指向结构的指针,当结构很大时这在Go中很常见。它也有一些状态,所以如果复制它可能会令人困惑。做一个func文字是没有意义的;我不明白为什么这是一个选项。

+0

是的,func文字只是它抛出的错误,当你不把它设置为指针。 –

2

因为这就是函数的工作原理。他们有争论,当你调用它们时,你必须提供必要的参数。类型也必须相同。

我认为你真的在问,它为什么这样设计?

因为您在向根"/"发出请求时要调用http.HandleFunc的代理。在大多数情况下,当一个RESTful API处理请求时,它需要知道请求中的信息,比如头部,查询参数和/或帖子主体等。如果你不想使用这些信息,不必要,将一个引用传递给一个函数的开销并不大。但是对于几乎所有的实际用例,数据都是需要的,因此它被包含在内,因此它在您提供的代表中成为参数。从实施的持续性来看,他们需要知道您提供的方法签名是什么,以便他们可以调用它。

为了澄清,您正在查看的是您作为http.HandleFunc的第二个参数func所需的签名。第一个参数是路径。当对所提供的路径进行http请求时,它会调用该方法。该代码将调用该参数称为handler,它需要一个一致的定义,以便它可以执行handler(resp, req),而不必为了调用代码而执行反射或切换或其他控制流。

+1

很多好吃的东西,我不得不深入,即委托,反射,控制流大声笑,但我会认为这是最正确的答案。感谢您的努力!我会把这一切都看出来:) –

+1

@MatthewHarwood记住我的描述是相当抽象的。这样做的代码本身就在这里; http://golang.org/src/net/http/server.go如果你想看看'HandleFunc'实际上做了什么'func(w http.ResponseWriter,r * http.Request)'参数。此外,请注意,您可以在其他地方通常使用该sig定义函数,并按名称传递它。 – evanmcdonnal

相关问题