我想通过在函数Request
中引用来设置Response
结构字段request
,以便在下面的主函数中进一步使用它。不幸的是,我收到以下错误:
{Status: StatusCode:0 Proto: ProtoMajor:0 ProtoMinor:0 Header:map[] Body:<nil> ContentLength:0 TransferEncoding:[] Close:false Uncompressed:false Trailer:map[] Request:<nil> TLS:<nil>}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x4922d1]
goroutine 1 [running]:
io.copyBuffer(0x72dbc0, 0xc0000a8008, 0x0, 0x0, 0xc000196000, 0x8000, 0x8000, 0xb9, 0x0, 0x0)
/usr/lib/go/src/io/io.go:402 +0x101
io.Copy(...)
/usr/lib/go/src/io/io.go:364
main.main()
/home/y/code/scmc/foo.go:49 +0x20d
exit status 2
该代码如下所示:
package main
import (
"fmt"
"io"
"net/http"
"os"
)
type Request struct {
Method string
Url string
Reader io.Reader
Response *http.Response
}
func request(r Request) error {
request, err := http.NewRequest(r.Method, r.Url, r.Reader)
if err != nil {
return err
}
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
return err
}
if r.Response != nil {
r.Response = response
}
return nil
}
func main() {
var r http.Response
if err := request(Request{
Method: "GET",
Url: "http://google.com",
Response: &r,
}); err != nil {
panic(err)
}
fmt.Printf("%+v\n", r)
if _, err := io.Copy(os.Stdout, r.Body); err != nil {
panic(err)
}
}
我究竟做错了什么?
最佳答案
client.Do()
返回一个指针: *http.Response
。如果要从函数中“传送”一个*http.Response
指针值,则需要一种可以设置的该类型的指针值。该指针值必须为**http.Response
类型(注意:指向指针的指针):
type Request struct {
Method string
Url string
Reader io.Reader
Response **http.Response
}
在
request()
函数中,您需要设置指向的值:if r.Response != nil {
*r.Response = response
}
当调用
request()
时:var r *http.Response
if err := request(Request{
Method: "GET",
Url: "http://google.com",
Response: &r,
}); err != nil {
panic(err)
}
以此类推:
如果您想转出
int
值:func do(i *int) {
*i= 10
}
// Calling it:
var i int
do(&i)
传送
*int
值:func do(i **int) {
x := 10
*i = &x
}
// Calling it:
var i *int
do(&i)
关于pointers - 通过引用设置结构中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59213195/