[英]Set field in struct by reference
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.我想在函数
request
中通过引用设置Request
结构字段Response
,以便在主函数的下面进一步使用它。 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
. client.Do()
返回一个指针: *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.如果你想从你的函数中“传输”一个
*http.Response
指针值,你需要一个指向你可以设置的类型的指针值。 That pointer value has to be of type **http.Response
(note: pointer to pointer):该指针值必须是
**http.Response
类型(注意:指向指针的指针):
type Request struct {
Method string
Url string
Reader io.Reader
Response **http.Response
}
Inside your request()
function you need to set the pointed value:在
request()
函数中,您需要设置指向的值:
if r.Response != nil {
*r.Response = response
}
And when calling request()
:当调用
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:如果您想转出一个
int
值:
func do(i *int) {
*i= 10
}
// Calling it:
var i int
do(&i)
To transfer out an *int
value:要传出
*int
值:
func do(i **int) {
x := 10
*i = &x
}
// Calling it:
var i *int
do(&i)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.