实现Reader接口

msc*_*ett 3 go

我理解Go接口的一般概念.但是,我最近正在考虑实现io.Reader界面,这让我很困惑.我发现这篇文章并没有多大帮助.

Reader接口和golang中的Read方法

首先,接受的答案是使用io.ReaderRead功能,据我可以告诉永远不会实现.其次,该Read功能如何在类似的情况下工作ioutil.ReadAll.它需要一些实现io.Reader接口并返回一片字节的东西.我不明白是什么东西只返回一个int并且err可以被处理成一片字节.

编辑:

我在疯狂的IRC频道得到了帮助,这就是你如何实际实现一个http://play.golang.org/p/ejpUVOx8jR的答案.非常感谢go社区.

编辑2:

如下所述,在strign大于缓冲区的情况下,上述实现将失败.这是一个更健全的实现http://play.golang.org/p/t4Zg8TnF33.

Ton*_*nas 9

您传递Read字节切片.Read应该把字节放在里面.由于切片只是对数组的引用,因此更改切片的内容会更改基础数组,因此调用者Read可以只检查它传递给它的切片.

ioutil.ReadAll创建一个缓冲区并调用ReadFrom它.重复ReadFrom调用Read,增加缓冲区的大小,直到Read通过返回io.EOF错误告诉它已经用尽.亲眼看看.

您链接的答案确实实现了io.Reader界面.它正在宣布一种方法Read(p []byte) (n int, e error).这就是所需要的.


小智 8

tez 提供的更新答案完全有效,但这里有一个我认为使用 Go 的更干净的替代方案copy

type Reader struct {
    data []byte
    readIndex int64
}

func (r *Reader) Read(p []byte) (n int, err error) {
    if r.readIndex >= int64(len(r.data)) {
        err = io.EOF
        return
    }

    n = copy(p, r.data[r.readIndex:])
    r.readIndex += int64(n)
    return
}
Run Code Online (Sandbox Code Playgroud)

通过使用copy,您不必担心溢出p []byte。这也不会耗尽/破坏您的阅读器上的任何状态,而只是使用readIndex.

完整示例在这里: https: //play.golang.org/p/8QTECCkies

这种策略可以在 Go 的一些核心包中看到(即https://golang.org/src/strings/reader.go