LimitedReader 只读一次

问题描述 投票:0回答:1

我试图通过学习 gopl book 来理解 Go。我在尝试实现 LimitReader 功能时卡住了。我意识到我有两个问题,所以让我把它们分开。

第一期

官方文档的描述是这样说的:

A LimitedReader 从 R 中读取,但将返回的数据量限制为仅 N 个字节。每次调用 Read 都会更新 N 以反映新的剩余数量。当 N <= 0 or when the underlying R returns EOF.

时 Read 返回 EOF

OK,所以我的理解是我可以从 io.Reader type 读取很多次,但我总是被限制在 N 字节。运行这段代码向我展示了一些不同的东西:

package main

import (
    "fmt"
    "io"
    "log"
    "strings"
)

func main() {
    r := strings.NewReader("some io.Reader stream to be read\n")
    lr := io.LimitReader(r, 4)
    b := make([]byte, 7)
    n, err := lr.Read(b)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Read %d bytes: %s\n", n, b)

    b = make([]byte, 5)
    n, _ = lr.Read(b)
    // If removed because EOF
    fmt.Printf("Read %d bytes: %s\n", n, b)
}
// Output:

// Read 4 bytes: some
// Read 0 bytes:
// I expect next 4 bytes instead

好像这种类型的对象只能读取一次。不太确定,但也许 io.go 源代码中的这一行 可以更改为 l.N = 0。主要问题是为什么这段代码和文档描述不一致?

第二期

当我遇到第一个问题时,我试图显示当前的 N 值。如果我把 fmt.Println(lr.N) 放在上面的代码中,它就无法编译 lr.N undefined (type io.Reader has no field or method N)。我意识到我仍然不明白 Go 接口的概念。

这是我的 POV(基于上面的列表)。使用 io.LimitReader 函数创建 LimitedReader 对象(参见 source code)。由于此对象包含带有适当签名的 Read 方法,因此其接口类型为 io.Reader。这就是 io.LimitReader 返回 io.Reader 的原因,对吧?好的,所以一切都在一起。

问题是:为什么lr.N无法访问?正如我对这本书的正确理解,接口类型只要求数据类型包含一些方法。仅此而已。

go interface io reader
1个回答
0
投票

LimitedReader 限制可以读取的数据总大小,而不是每次读取调用时可以读取的数据量。也就是说,如果你设置limit为4,你可以执行4次1字节的读取,或者1次4字节的读取,之后,所有的读取都会失败。

对于你的第二个问题:lr是一个io.Reader,所以你不能阅读lr.N。但是,您可以使用类型断言访问底层具体类型:lr.(*io.LimitedReader).N 应该有效。

© www.soinside.com 2019 - 2024. All rights reserved.