繁体   English   中英

通过引用在结构中设置字段

[英]Set field in struct by reference

我想在函数request中通过引用设置Request结构字段Response ,以便在主函数的下面进一步使用它。 不幸的是,我收到以下错误:

{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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM