为了账号安全,请及时绑定邮箱和手机立即绑定

如何正确检查 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 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信