【问题标题】:Why must the http.Request argument be a pointer?为什么 http.Request 参数必须是一个指针?
【发布时间】:2015-06-30 18:18:32
【问题描述】:
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 中的*

github.com/creating_web_app_go/main.go:8:不能在 http 的参数中使用 func 文字(类型 func(http.ResponseWriter, http.Request))作为类型 func(http.ResponseWriter, *http.Request)。处理函数

我对 Go 和指针都很陌生。

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

【问题讨论】:

  • 为什么是-1?这真的是一个问得不好的问题吗?
  • 其实这是一个非常好的问题 imo
  • @ArmeenHarwood 我们必须添加 * 是有原因的,所以我认为这是一个糟糕的问题

标签: pointers go


【解决方案1】:

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

【讨论】:

  • 是的,func 文字只是当你不将它设置为指针时它抛出的错误。
【解决方案2】:

因为这就是函数的工作方式。它们有参数,当您调用它们时,您必须提供所需的参数。类型也必须相同。

我想你真的在问;为什么要这样设计?

因为您为http.HandleFunc 提供了一个委托,以便在向根"/" 发出请求时调用。在大多数情况下,当 RESTful API 处理请求时,它需要知道请求中的信息,例如标头、查询参数和/或帖子正文……不必,将引用传递给函数的开销并不大。但是对于几乎每个实际用例,都需要数据,因此它被包含在内,因此它在您提供的委托中成为一个参数。从他们实现的角度来看,他们需要知道您提供的方法签名是什么,以便他们可以调用它。

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

【讨论】:

  • 我必须深入研究其中的许多美味部分,即委托、反射、控制流,哈哈,但我认为这是最正确的答案。感谢您的努力!我会弄清楚这一切的:)
  • @MatthewHarwood 请记住我的描述相当抽象。执行此操作的代码本身在这里; golang.org/src/net/http/server.go 如果您想查看 HandleFunc 实际使用它的 func(w http.ResponseWriter, r *http.Request) 参数做什么。另外,请注意,您可以在其他地方通常使用该 sig 定义一个函数并通过名称传递它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 2018-04-23
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多