pointers - 通过引用设置结构中的字段

标签 pointers go struct

我想通过在函数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/

相关文章:

c - 带 vector 的结构指针 - 段错误

c - 指向不同结构内的结构的指针。 C

go - 使用 OAuth2.0 作为 webapp 的授权系统

go - 为什么只能给指针赋别名?

go - 下载模块的原始代理

c - 将 bool 字段添加到结构时出现语法错误( ‘:’ 标记之前应为 ‘,’ 、 ‘;’ 、 ‘}’ 、 ‘__attribute__’ 或 ‘=’ )

无法传递 `#define` 作为函数参数,但可以传递 `#define` 的数组[n]

c++ - 递增数组变量时需要不一致的左值错误

c - 如何将项目动态添加到动态数组

c++ - 指针)是否有可能已经占据(ptr + 1)?