簡體   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