-2

我正在玩 Golang tour,我想知道为什么使用裸 return 会给我正确的结果,而正常的结果却没有。这是我遇到此问题的练习https://tour.golang.org/methods/12

目标是创建一个可以破译 rot13 的阅读器。并且 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)
}

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

有人可以解释为什么吗?先感谢您。

4

2 回答 2

3

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 
}
于 2015-06-18T10:24:08.733 回答
3

返回不是问题,但在第一种情况下,您在转换之前读取数据,在第二种情况下,您在缓冲区中转换垃圾,然后才读取数据(并简单地传递已读取的内容来自底层读者)。

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

看一下 的文档io.Reader,它应该让您对这个接口如何工作有更多的了解。

于 2015-06-18T10:27:15.883 回答