登录
首页 >  Golang >  Go问答

Golang *bytes.Buffer 空指针引发严重问题

来源:stackoverflow

时间:2024-03-07 09:27:26 177浏览 收藏

怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《Golang *bytes.Buffer 空指针引发严重问题》,涉及到,有需要的可以收藏一下

问题内容

我遇到了与 https://github.com/golang/go/issues/26666 相同的问题,因为我的 http 请求有一个包装函数。

有时我需要请求:

body := new(bytes.buffer)
json.newencoder(body).encode(h)
req("post", "http://example.com", body)

有时很简单:

req("get", "http://example.com", nil)
runtime error: invalid memory address or nil pointer dereference

我最终得到:

req("get", "http://example.com", new(bytes.buffer))

但我不确定这样做是否正确。

功能:

func req(method string, url string, body *bytes.buffer) int {
req, err := http.newrequest(method, url, body)
req.header.set("content-type", "application/json")
req.setbasicauth(user, psw)
resp, err := client.do(req)
checkerr(err)
if resp.statuscode > 500 {
    time.sleep(30 * time.second)
    resp, err = client.do(req)
    checkerr(err)
}
defer resp.body.close()
return resp.statuscode
}

更新功能:

func req(method string, url string, body io.Reader) int {
    req, err := http.NewRequest(method, url, body)
    req.Header.Set("Content-Type", "application/json")
    req.SetBasicAuth(user, psw)
    resp, err := client.Do(req)
    checkErr(err)
    defer resp.Body.Close()
    if resp.StatusCode >= 500 {
        time.Sleep(30 * time.Second)
        req, err := http.NewRequest(method, url, body)
        req.Header.Set("Content-Type", "application/json")
        req.SetBasicAuth(user, psw)
        resp, err := client.Do(req)
        checkErr(err)
        defer resp.Body.Close()
    }
    return resp.StatusCode
}

func checkErr(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

解决方案


http.NewRequest() 中的 body 是可选的,因此在执行 get 请求时传递 nil 是可以接受的。

问题在于 http.newrequestbody 参数是接口类型:io.reader,并且您试图传递具体类型 *bytes.buffer 的值。发生的情况是,此 nil 指针将包装在非 nil 接口值中,并将作为正文传递给 http.newrequest

如果您没有主体,请显式传递 nil,如下所示:

func req(method string, url string, body *bytes.buffer) int {
    var bodytopass io.reader
    if body != nil {
        bodytopass = body
    }
    req, err := http.newrequest(method, url, bodytopass)

    // ....
}

然后你可以这样称呼它:

req("get", "http://example.com", nil)

尽管最好的情况是您的 req() 函数首先采用 io.reader ,这样您就不必显式检查其值:

func req(method string, url string, body io.reader) int {
    req, err := http.newrequest(method, url, body) // you may pass it as-is

    // ....
}

您也可以使用 nil 或非 nil *bytes.buffer 来调用它:

req("GET", "http://example.com", nil) // OK

req("POST", "http://example.com", bytes.NewBufferString("data")) // Also OK

更多详情请参见Hiding nil values, understanding why golang fails here

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Golang *bytes.Buffer 空指针引发严重问题》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>