I want to set the Request
struct field Response
by reference in the function request
in order to use it further below in the main function. Unfortunately, I get the following error:
{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
The code looks as follows:
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)
}
}
What am I doing wrong?
client.Do()
returns a pointer: *http.Response
. If you want to "transfer" a *http.Response
pointer value out of your function, you need a pointer value to this type which you may set. That pointer value has to be of type **http.Response
(note: pointer to pointer):
type Request struct {
Method string
Url string
Reader io.Reader
Response **http.Response
}
Inside your request()
function you need to set the pointed value:
if r.Response != nil {
*r.Response = response
}
And when calling request()
:
var r *http.Response
if err := request(Request{
Method: "GET",
Url: "http://google.com",
Response: &r,
}); err != nil {
panic(err)
}
For analogy:
If you'd want to transfer out an int
value:
func do(i *int) {
*i= 10
}
// Calling it:
var i int
do(&i)
To transfer out an *int
value:
func do(i **int) {
x := 10
*i = &x
}
// Calling it:
var i *int
do(&i)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.