首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现Reader接口

实现Reader接口
EN

Stack Overflow用户
提问于 2015-01-28 00:14:33
回答 3查看 12.6K关注 0票数 10

我理解Go接口的一般概念。然而,我最近正在研究实现io.Reader接口,这让我感到困惑。我发现这篇文章没有多大帮助。

Reader interface and the Read method in golang

首先,公认的答案是使用io.ReaderRead函数,据我所知,这个函数从来没有实现过。其次,Read函数在ioutil.ReadAll这样的上下文中是如何工作的。它接受实现io.Reader接口的东西,并返回一个字节切片。我不明白如何将只返回interr的东西处理成字节切片。

编辑:

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

编辑2:

如下所述,在strign大于buffer的情况下,上面的实现将失败。这是一个更合理的实现http://play.golang.org/p/t4Zg8TnF33

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-28 00:27:20

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

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

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

票数 12
EN

Stack Overflow用户

发布于 2016-11-17 06:50:31

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

代码语言:javascript
复制
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溢出。这也不会耗尽/破坏阅读器上的任何状态,而只是使用readIndex迭代它。

完整示例如下:https://play.golang.org/p/8QTECCkies

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

票数 4
EN

Stack Overflow用户

发布于 2015-01-29 04:45:02

只需注意,您在此处(http://play.golang.org/p/ejpUVOx8jR)实现的Read()方法是不正确的。您没有考虑到所提供的p []byte参数的容量。如果它小于你的测试字符串(例如:http://play.golang.org/p/DhcY0hJ0c0),你会得到一个“索引超出范围”的警告。

您可以考虑一种不同的方法,比如http://play.golang.org/p/t4Zg8TnF33

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28174970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档