golang 中"r *http.Request"的实际参数是从哪来的

2018-12-11 13:20:08 +08:00
 wsseo
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)
}

作为 golang 初学者,不能理解"r *http.Request "为什么不需要实际参数,r 是存储在哪里的。 "w http.ResponseWriter"也不需要实际参数吗。这从语法上怎么理解?

2122 次点击
所在节点    程序员
7 条回复
liuxey
2018-12-11 13:23:51 +08:00
实际参数不是 r 吗?我觉得楼主基础知识有点缺,看不懂你的问题
wsseo
2018-12-11 13:30:38 +08:00
@liuxey 我也觉得。我理解的是 r 是形式参数,函数不是一般需要传递实际参数吗?像这样调用的时候传递实参 func_b(r)
xlui
2018-12-11 13:40:14 +08:00
@wsseo 就跟 Java EE 中 servlet 的参数一样,实参是容器在调用处理方法时传进去的。具体到这个例子,匿名函数的实参是在请求 / 时 http 包内部在回调匿名函数时传进去的,实际应用中我们不需要关心。个人理解。
liuxey
2018-12-11 13:45:16 +08:00
@wsseo #2 我大概懂你问的意思了,这些概念好久远

http.HandleFunc 的形式参数有两个,pattern 和 handler,handler 是一个 func,签名就是 func(ResponseWriter, *Request),那么你代码里写的:

func(w http.ResponseWriter, r *http.Request){
w.Write([]byte("hello world"))
}

就是 handler 的实际参数,它的类型是 func,这里只是将这个 func 注册到默认的 defaultServeMux 中,具体传递实参是在运行中接受请求时调用的,不是通过 http.HandleFunc 调用,如果你开发过函数式类型的语言的话,这里应该很好理解。

你可以花个一天时间看下 Golang http 的实现,源码很简单的(如何你想彻底搞懂 http 模块的话)
AzadCypress
2018-12-11 13:49:12 +08:00
func main() {
http.HandleFunc("/", func_b)
http.ListenAndServe(":8000", nil)
}
func func_b(w http.ResponseWriter, r *http.Request){
w.Write([]byte("hello world"))
}
写成这样应该能看明白,参数哪里来的你得去看 http.HandleFunc 的实现
wsseo
2018-12-11 14:04:48 +08:00
@liuxey 大概知道什么意思了
tiedan
2018-12-11 17:49:04 +08:00
参数在 HandleFunc 里面传进去的啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/516469

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX