1 回答
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)是您的工作。
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报