gpt4 book ai didi

go - Go rot13Reader 缓冲区在读取功能完成后未更新

转载 作者:IT王子 更新时间:2023-10-29 01:40:22 24 4
gpt4 key购买 nike

这是我使用 strings.Map 实现的练习(rot13 函数直接来自 golang 的文档)。问题是在 Read 函数返回后,缓冲区似乎没有被修改。这是代码:

package main

import (
"io"
"os"
"strings"
"fmt"
)

type rot13Reader struct {
r io.Reader
}

func (reader *rot13Reader) Read(b []byte) (int, error) {
rot13 := func(r rune) rune {
switch {
case r >= 'A' && r <= 'Z':
return 'A' + (r-'A'+13)%26
case r >= 'a' && r <= 'z':
return 'a' + (r-'a'+13)%26
}
return r
}
n, err := reader.r.Read(b)
result := []byte(strings.Map(rot13, string(b)))
b = []byte(result)
fmt.Println(string(b))
return n, err
}

func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}

和输出:

You cracked the code!
Lbh penpxrq gur pbqr!You cracked the code!

明明在Read函数中已经修改了buffer,但是返回后好像不是这样。如果我要注释掉 fmt.Println(string(b)),输出将只是:

Lbh penpxrq gur pbqr!

Readers 和 Writers 有什么我应该知道的古怪之处吗?

最佳答案

在 Go 中,所有参数都按值传递,就好像通过赋值给参数或接收者(浅拷贝)一样。

在 Go 中, slice 实现为

type slice struct {
array unsafe.Pointer
len int
cap int
}

当 slice 按值传递时,返回后,您将看不到您对 struct 字段的副本所做的任何更改。您只会看到对底层数组元素的任何更改。


在你的例子中,你覆盖了 b (array, cap, len),一个副本。

b = []byte(result)

当您返回时,副本将被丢弃。


您要做的是更改barray 的元素。

例如,

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)
}

Playground :https://play.golang.org/p/0LDYmzrrgty

输出:

You cracked the code!

The Go Blog: Go Slices: usage and internals

关于go - Go rot13Reader 缓冲区在读取功能完成后未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57171860/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com