解决第23次旅行任务有什么问题?

时间:2016-07-26 18:53:28

标签: go

有一个游览。我已经解决了https://tour.golang.org/methods/23这样的问题:

func (old_reader rot13Reader) Read(b []byte) (int, error) {
    const LEN int = 1024
    tmp_bytes := make([]byte, LEN)
    old_len, err := old_reader.r.Read(tmp_bytes)
    if err == nil {
        tmp_bytes = tmp_bytes[:old_len]
        rot13(tmp_bytes)
        return len(tmp_bytes), nil
    } else {
        return 0, err
    }
}

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

rot13正确且返回前调试输出显示正确的字符串。但为什么控制台没有输出?

2 个答案:

答案 0 :(得分:3)

Read的{​​{1}}方法需要对提供给它的字节切片进行操作。你正在阅读一个新的切片,而不是修改原始切片。

在整个Read方法中使用io.Reader

b

答案 1 :(得分:1)

您永远不会在读者中修改ValueError: dictionary update sequence element #0 has length 6; 2 is required b的{​​{1}}函数的语义是您将数据直接放入io.Reader的基础数组中。

假设Read功能也就地修改,这将有效(编辑:我试图让这些代码保持接近您的版本,这样您就可以更容易地看到更改的内容。 JimB的解决方案是解决这个问题的更惯用的方法):

b

示例(带有存根rot13()):https://play.golang.org/p/vlbra-46zk

另一方面,从惯用的角度来看,func (old_reader rot13Reader) Read(b []byte) (int, error) { tmp_bytes := make([]byte, len(b)) old_len, err := old_reader.r.Read(tmp_bytes) tmp_bytes = tmp_bytes[:old_len] rot13(tmp_bytes) for i := range tmp_bytes { b[i] = tmp_bytes[i] } return old_len, err } 不是一个合适的接收者名称(rot13()也不是一个合适的变量名称)。 Go更喜欢短接收者名称(在这种情况下比较old_readerold_len),也更喜欢camelcase到下划线(下划线实际上会发出r警告)。

Edit2 :更加惯用的代码版本。保持相同的行动机制,只是稍微清理了一下。

rdr

由此,删除golint字节切片并使用目标func (rdr rot13Reader) Read(b []byte) (int, error) { tmp := make([]byte, len(b)) n, err := rdr.r.Read(tmp) tmp = tmp[:n] rot13(tmp) for i := range tmp { b[i] = tmp[i] } return n, err } 直接导致JimB解决问题的惯用方法。

Edit3 :已更新以解决Paul在评论中指出的问题。