实现 Reader 接口

Implementing Reader interface

我了解 Go 接口的一般概念。但是,我最近正在研究实现 io.Reader 接口,这让我感到困惑。我发现这个 post 并没有多大帮助。

Reader interface and the Read method in golang

首先,接受的答案是使用 io.ReaderRead 函数,据我所知,该函数从未实现过。其次,Read 函数如何在 ioutil.ReadAll 之类的上下文中工作。它需要实现 io.Reader 接口和 returns 字节片段的东西。我不明白如何将仅返回 interr 的内容处理成字节片段。

编辑:

我在 go-nuts IRC 频道中得到了帮助,这是关于您可能如何实际实施一个 http://play.golang.org/p/ejpUVOx8jR 的答案。非常感谢 go 社区。

编辑 2:

正如下面所指出的,如果字符串大于缓冲区,上面的实现将失败。这是一个更理智的实现 http://play.golang.org/p/t4Zg8TnF33.

你传递 Read 字节片。 Read 应该将字节放入其中。由于切片只是对数组的引用,更改切片的内容会更改底层数组,因此 Read 的调用者随后可以检查它传递给它的切片。

ioutil.ReadAll 创建一个缓冲区并在其上调用 ReadFromReadFrom 重复调用 Read,增加缓冲区的大小,直到 Read 通过返回 io.EOF 作为错误告诉它已经耗尽。 See for yourself.

您 link 的回答确实实现了 io.Reader 接口。它正在声明一个方法 Read(p []byte) (n int, e error)。这就是所有需要的。

请注意,您在此处实施了 Read() 方法 (http://play.golang.org/p/ejpUVOx8jR) is incorrect. You do not account for a capacity of the provided p []byte argument. You'll get an "index out of range" panic if it is smaller than your test string (ex: http://play.golang.org/p/DhcY0hJ0c0)。

您可能会考虑像这样的不同方法 - http://play.golang.org/p/t4Zg8TnF33

更新 我注意到我的实现中存在内存泄漏。固定版本在这里 - http://play.golang.org/p/9BbS54d8pb。这表明即使是微不足道的代码有时也不是那么微不足道:)

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
}

通过使用copy,您不必担心溢出p []byte。这也不会 drain/destroy 您在 reader 上的任何状态,而只是用 readIndex.

迭代它

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

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