在Go HTTP处理程序中,为什么ResponseWriter是一个值,但Request是一个指针?

我通过编写GAE的应用程序来学习Go,这是一个处理函数的签名:

func handle(w http.ResponseWriter, r *http.Request) {} 

我在这里是新手指针,那么为什么Request对象是一个指针,但是ResponseWriter不是? 有没有需要这样做,或者这只是使某种先进的基于指针的代码可能?

你得到的w是一个指向非导出typeshttp.response的指针,但是作为ResponseWriter是一个接口,这是不可见的。

从server.go :

 type ResponseWriter interface { ... } 

另一方面, r是一个指向具体结构的指针,因此需要明确地加以确定:

来自request.go :

 type Request struct { ... } 

http.ResponseWriter是一个接口,实现这个接口的现有types是指针。 这意味着不需要使用指向这个接口的指针,因为它已经被指针“支持”了。 这个概念是由这里的一个开发人员描述的。尽pipe一个实现http.ResponseWriter的types不需要是一个指针,但它不是实际的,至less不在http服务器中。

http.Request不是一个接口,它只是一个结构,因为我们想要改变这个结构,并让Web服务器看到这些变化,它必须是一个指针。 如果它只是一个结构体的值,我们只需要修改它的副本,即调用我们的代码的Web服务器看不到。

我认为Request对象作为指针传递的主要原因是Body字段。 对于给定的HTTP请求,主体只能读取一次。 如果Request对象被克隆,如果它不作为指针传递,我们将有两个对象具有不同的信息,有多less已经从正文读取。