最近我在golang中遇到了一些困惑的事情。
package main
import (
"net/http"
"bytes"
"fmt"
"io/ioutil"
)
func createRequest(method, uri string, data *bytes.Buffer) string {
req, err := http.NewRequest(method, uri, data)
if err != nil {
return ""
}
req.Close = true
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return ""
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ""
}
return string(respBody)
}
func createRequestNoBody(method, uri string) string {
req, err := http.NewRequest(method, uri, nil)
if err != nil {
return ""
}
req.Close = true
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return ""
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ""
}
return string(respBody)
}
func main() {
data := createRequestNoBody("GET", "http://google.com")
if len(data) != 0 {
fmt.Println("First Request Ok")
}
data = createRequest("GET", "https://google.com", nil)
if len(data) != 0 {
fmt.Println("Second Request OK")
}
}
当直接将nil传递给http.NewRequest
的时候,这段代码可以在createRequestNoBody
函数中正常工作,但是在调用函数中将*bytes.Buffer
设置为nil
时,调用createRequest
会导致恐慌。
http库中的NewRequest函数具有以下原型:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
其中io.Reader
是一个接口。
我不确定为什么通过变量传递的nil会导致NewRequest中的body
变成非nil。
有人能解释一下为什么createRequest
方法会导致恐慌吗?在NewRequest
方法内部,data = createRequest("GET", "https://google.com", nil)
中的nil参数是如何变成非nil的呢?
data
的值是(nil, nil)还是(*bytes.Buffer,nil)?我不确定什么时候它变成了(*bytes.Buffer,nil),这就是问题所在。 - soluwalanadata
是nil
,但类型为*bytes.Buffer
。 - JimB