【问题标题】:Why the request is a pointer variable? Why not a reference variable?为什么请求是指针变量?为什么不是参考变量?
【发布时间】:2017-06-13 04:45:22
【问题描述】:

我已经学习 GO 语言一个月了。我已经用 java 编码超过 4 年了。在 java 中,Request 和 Response 都是对象引用。但是,对于 GoLang,Response 是对象引用,Request 是指针引用。

引用和指针一样,是一个可以用来间接引用另一个对象的对象。引用声明与指针声明的语法结构基本相同。

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

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

除了上面的问题,这里的请求是一个任意指针。即请求尚不存在,但指针已指向内存位置。如果我的理解有误,请多指教。

【问题讨论】:

  • golang 中没有引用,只有指针。并且所有参数都是按值传递的。
  • @zzn 我没想到会有一个客观的答案。能否请您抽出宝贵的时间来详细说明一下?
  • 正如@zzn 所说:Go 完全没有“通过引用传递”的概念,因此在 Go 中谈论或推理引用毫无意义。推测 Go 将如何从“引用”中获利是非常深奥的(因为它不会发生)。 http.Request 上的几个方法修改了请求,因此需要一个指针接收器,因此请求在任何地方都作为指针处理。这称为一致性,与语法糖或可读性无关。
  • 关于附加问题“如果我的理解有误,请多指教。”是的,完全。 r 是指向某个现有请求还是 nil(没有其他选项)取决于 hello 的调用方式,仅此而已。从tour.golang.org/moretypes/1开始,通过 Tour of Go 了解指针工作

标签: pointers go reference


【解决方案1】:

In Go HTTP handlers, why is the ResponseWriter a value but the Request a pointer? 的副本

主要是 ResponseWriter 是一个接口(您可能想了解更多关于接口的信息,以防万一您还没有了解它)。只是要补充一点,请求是一个指向结构的指针-拥有请求结构的副本是没有意义的(当按值传递时会发生这种情况),所以它不是作为结构传递的(尤其是当你传递它时)下游到其他函数,你可以直接把它传下来)

【讨论】:

  • 感谢您指出正确的来源。 airs.com/blog/archives/281这个博客让我更有意义。
  • “ResponseWriter 是一个接口”是一个重要的细节 - 这意味着您收到的 ResponseWriter 也是一个指针
【解决方案2】:

正如在此处和其他地方的许多其他答案中正确提到的那样,ResponseWriter 是一个接口,其含义已在 SO 答案和博客中详细描述。

我想解决的是我认为这里存在的一个大而危险的误解,即请求是通过“引用”传递的原因(尽管这样的事情在 Go中并不真正存在) >) 是“我们希望对其进行更改对服务器可见”。

引用其他人的几个答案:

[..]它只是一个结构体,既然我们想改变这个结构体并让网络服务器看到这些变化,它必须是一个指针[..]SO

[..]处理程序对请求的更改需要对服务器可见,因此我们仅通过引用而不是通过值传递它 [..]SO

这是错误的;其实the docs explicitly warn against tampering with / mutating the request:

除了读取正文,处理程序不应修改提供的请求。

恰恰相反,不是吗? :-)

如果您想更改请求,例如在将跟踪标头传递给中间件链中的下一个处理程序之前附加一个跟踪标头您必须复制请求并将复制的版本传递到链中。

如果我们明确告诉人们不要改变请求,为什么还要使用指针? 性能Request 是一个大型结构,复制它会降低性能,尤其是考虑到较长的中间件链。团队必须取得平衡,这绝对不是一个理想的解决方案,但这里的权衡显然是在性能方面(而不是 API 安全)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多