为什么请求是一个指针变量?为什么不是参考变量?

时间:2017-06-13 04:45:22

标签: pointers go reference

我一直在学习GO Lang一个月了。我已经用java编写了4年多的代码。在java中,Request和Response都是对象引用。但是,当涉及GoLang时,Response是一个对象引用,Request是一个指针引用。

引用(如指针)是一个可用于间接引用另一个对象的对象。引用声明与指针声明具有基本相同的语法结构。

func hello(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello world!")
}

除了可读性视角和语法糖之外,使用Request作为指针变量还有其他任何意图。

添加上述问题,这里的请求是一个任意指针。即请求尚未存在,但指针已经指向内存位置。如果我的理解是错误的,请多说清楚。

2 个答案:

答案 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安全性)。