2 回答
TA贡献1824条经验 获得超5个赞
在 Go 中,所有参数都按值传递,就像通过分配给参数或接收者(浅拷贝)一样。
在 Go 中,切片的实现为
type slice struct {
array unsafe.Pointer
len int
cap int
}
当切片按值传递时,返回后,您将看不到对字段副本所做的任何更改struct。您只会看到底层数组元素的任何更改。
在您的情况下,您将覆盖b( array, cap, len) 副本。
b = []byte(result)
当您返回时,该副本将被丢弃。
您想要做的是更改bs的元素array。
例如,
package main
import (
"io"
"os"
"strings"
)
func rot13(b byte) byte {
switch {
case b >= 'A' && b <= 'Z':
return 'A' + (b-'A'+13)%26
case b >= 'a' && b <= 'z':
return 'a' + (b-'a'+13)%26
}
return b
}
type rot13Reader struct {
r io.Reader
}
func (reader *rot13Reader) Read(b []byte) (int, error) {
n, err := reader.r.Read(b)
b = b[:n]
for i := range b {
b[i] = rot13(b[i])
}
return n, err
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
TA贡献1829条经验 获得超13个赞
我不太确定,所以请在服用下面的食物时加入几粒到几磅的盐。
首先,您应该尽早添加错误检查:
n, err := reader.r.Read(b)
if err != nil && err == io.EOF {
fmt.Printf("\n%s, %d bytes read", err, n)
return n, err
}
添加后,输出就是您所期望的:
You cracked the code!
Lbh penpxrq gur pbqr!
EOF, 0 bytes read
这里的原因是读者应该返回 io.EOF,以防没有任何内容可供阅读。
那么你为什么会经历上述奇怪的行为呢?快速浏览一下源代码就会io.Copy
发现,b
分配一次并重用。但由于b
未修改(未读取任何字节)并且您访问它以从中读取,因此它仍然保留与以前相同的值。不过,我认为,根据最小意外原则,如果没有读到任何内容,底层io.Reader
应该是清晰的。b
- 2 回答
- 0 关注
- 147 浏览
添加回答
举报