我在玩Golang巡回演出,我想知道为什么使用裸返回给我正确的结果,而正常的结果却没有。这是我 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)
}
这不会改变输入流中的任何内容。
谁能解释为什么?提前谢谢你。
返回不是问题,但在第一种情况下,您在转换数据之前读取数据,在第二种情况下,您将在缓冲区中转换垃圾,然后才读取数据(并简单地传递从底层读取器读取的内容)。
虽然这不是正确性所必需的,但我建议您不要每次都转换整个缓冲区,而只转换已读取的部分,即将您的第一个示例从 for i, v := range b
更改为 for i, v := range b[:n]
。这是因为io.Read
调用无法修改切片b
的长度,而只能修改其内容。
看看 io.Reader
的文档 ,它应该可以让您更多地了解此接口的预期工作方式。
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
}