我一直在学习GO Lang一个月了。我已经用java编写了4年多的代码。在java中,Request和Response都是对象引用。但是,当涉及GoLang时,Response是一个对象引用,Request是一个指针引用。
引用(如指针)是一个可用于间接引用另一个对象的对象。引用声明与指针声明具有基本相同的语法结构。
func hello(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world!")
}
除了可读性视角和语法糖之外,使用Request作为指针变量还有其他任何意图。
添加上述问题,这里的请求是一个任意指针。即请求尚未存在,但指针已经指向内存位置。如果我的理解是错误的,请多说清楚。
答案 0 :(得分:1)
重复In Go HTTP handlers, why is the ResponseWriter a value but the Request a pointer?
主要是ResponseWriter是一个接口(您可能希望了解有关接口的更多信息,以防您没有检查过它)。只是要添加,请求是一个指向结构的指针 - 拥有请求结构的副本(通过值传递时发生)是没有意义的,因此它不作为结构传递(特别是当你传递它时,请考虑它)在其他功能的下游,您可以直接将其传递下去)
答案 1 :(得分:0)
正如在这里和其他地方的许多其他答案中正确提到的那样,ResponseWriter
是一个界面,并且其含义已在 SO 答案和博客中进行了详细描述。
我要解决的是我的感觉,这是一个巨大且危险的误解,原因是请求是通过“引用”传递的(尽管在 Go )是“我们希望对服务器进行更改”。
引用其他人的几个答案:
[..]它只是一个结构,由于我们要更改此结构并让Web服务器看到这些更改,因此它必须是一个指针[..] SO
[..]处理程序对Request的更改需要对服务器可见,因此我们仅通过引用而不是通过值[..] SO
这是错误的;实际上the docs explicitly warn against tampering with / mutating the request:
除了读取正文,处理程序不应修改提供的请求。
相反,不是吗? :-)
如果您想更改请求,例如在将跟踪标头传递到中间件链中的下一个处理程序之前,请添加跟踪标头您必须复制请求,并将复制的版本向下传递到链中。
如果我们明确告诉人们不要更改请求,为什么要使用指针? Performance (性能),Request
是一个大型结构,对其进行复制会降低性能,尤其是考虑到较长的中间件链时。团队必须权衡利弊,这绝对不是理想的解决方案,但是这里的权衡显然是在性能方面(而不是API安全性)。