为什么使用 naked return 和正常的 return 给我不同的结果?

Why using naked return and the normal return give me different results?

我正在玩 Golang 之旅,我想知道为什么使用 naked return 会给我正确的结果,而普通的却不会。这是我遇到这个问题的练习https://tour.golang.org/methods/12.

objective就是创造一个可以破译rot13的reader。并且rot13功能已经过测试。

func (r rot13Reader) Read(b []byte) (n int, err error) {
    n, err =  r.r.Read(b)
    for i, v := range b {
        b[i] = rot13(v)
    }
    return
}

上面的代码给出了正确的结果。

func (r rot13Reader) Read(b []byte) (int, error) {
    for i, v := range b {
    b[i] = rot13(v)
    }
    return r.r.Read(b)
}

这不会改变输入流的任何内容。

谁能解释一下为什么?提前谢谢你。

Read() 操作改变了输入数组 b。在第二个示例中,rot13() 操作被 Read() 操作覆盖。此外,rot13() 操作是在任何数据被读入数组之前执行的,因此您可能正在对垃圾数据执行 rot13()

如果你想让第二个例子工作,你需要写这样的东西:

func (r rot13Reader) Read(b []byte) (int, error) {
    n, err := r.r.Read(b)
    for i, v := range b {
    b[i] = rot13(v)
    }
    return n, err 
}

returns 没有问题,但在第一种情况下,您在转换数据之前读取数据,而在第二种情况下,您在缓冲区中转换垃圾数据,然后才读取数据(并简单地传递从底层 reader 读取的内容)。

虽然这不是正确性所必需的,但我建议您不要每次都转换整个缓冲区,而只转换已读取的部分,即将您的第一个示例从 for i, v := range b 更改为 for i, v := range b[:n]。那是因为 io.Read 调用无法修改切片 b 的长度,只能修改其内容。

看看 io.Reader 的文档,它应该会让您对该接口的预期工作方式有更多的了解。