亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何正確檢查 io.Reader 是否為 nil?

如何正確檢查 io.Reader 是否為 nil?

Go
慕無忌1623718 2022-12-05 17:25:29
如果你創建一個 type 變量bytes.Buffer(沒有初始化)并將它賦給一個 type 字段io.Reader,那么在檢查io.Readernil 之后會出現錯誤:invalid memory address or nil pointer dereference。如何正確檢查以避免此類錯誤?package mainimport (    "bytes"    "io"    "io/ioutil")type Request struct {    Body io.Reader}func main() {    var data *bytes.Buffer    request := &Request{        Body: data,    }    if request.Body != nil {        ioutil.ReadAll(request.Body) // panic: runtime error: invalid memory address or nil pointer dereference    }}
查看完整描述

1 回答

?
GCT1015

TA貢獻1827條經驗 獲得超4個贊

要檢查一個io.Reader(或任何其他接口)值是否為nil,您只需將它與 進行比較nil。


非nil io.Reader- 是否是有意義的實現,這是另一個問題。


例如,這個實現有意義嗎?


type panicReader struct{}


func (panicReader) Read(p []byte) (int, error) {

    panic("foo")

}

panicReader當然 implements io.Reader,但是每當你調用它的Read()方法時,它總是會 panic。


有bytes.Buffer。指向它的指針 implements io.Reader。但是調用指針值會出現恐慌Buffer.Read()。nil *bytes.Buffer但這不是因為您不能在nil指針接收器上調用方法,而是因為 的實現bytes.Buffer.Read()試圖取消引用指針接收器,而這種取消引用操作是導致恐慌的原因:


// Excerpt from bytes.Buffer.Read implementation 

func (b *Buffer) Read(p []byte) (n int, err error) {

    b.lastRead = opInvalid

    if b.empty() {

    // ...

}

您不能在這里做出一般性結論(目前)??吹竭@個io.Reader實現:


type myBuffer struct{}


var count int


func (*myBuffer) Read(p []byte) (int, error) {

    if len(p) > 0 {

        count++

        if count >= 10 {

            return 0, io.EOF

        }

        p[0] = 'a'

        return 1, nil

    }

    return 0, nil

}

*myBufferimplements io.Reader,它的Read()方法不使用指針接收器值。這是什么意思?您可以調用Read()一個nil *myBuffer值:


var data *myBuffer


request := &Request{

    Body: data,

}


if request.Body != nil {

    data, err := ioutil.ReadAll(request.Body)

    fmt.Println(string(data), err)

}

這將輸出(在Go Playground上嘗試):


aaaaaaaaa <nil>

所以結論是這樣的:通常具有指針接收器方法的類型需要非nil指針,因為它們使用指向對象(如果bytes.Buffer它們使用指向結構的字段)。要使用此類類型(對已實現的接口進行有意義的實現),您通常需要一個非nil指針值來使方法“工作”。myBuffer然而,正如上面的實現所示,這并不總是一個要求。始終閱讀所用類型和方法的文檔以避免此類誤用(例如嘗試使用 a nil *bytes.Buffer)是您的工作。


查看完整回答
反對 回復 2022-12-05
  • 1 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號