doufei9946 2019-07-23 20:39
浏览 37
已采纳

读取功能完成后,不会更新Go rot13Reader缓冲区的行程

Here is my implementation of the exercise using strings.Map (the rot13 function is straight out of golang's docs). The issue is that the buffer does not seem to be modified after the Read function returns. Here is the code:

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

and the output:

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

Clearly the buffer has been modified in the Read function, but it does not seem to be the case after it returns. If I were to comment out the fmt.Println(string(b)), the output would just be:

Lbh penpxrq gur pbqr!

Is there something quirky about Readers and Writers that I should know about?

  • 写回答

2条回答 默认 最新

  • douyanguo7964 2019-07-23 22:55
    关注

    In Go, all arguments are passed by value, as if by assignment to the parameter or receiver (a shallow copy).

    In Go, a slice is implemented as

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

    When the slice is passed by value, after you return, you will not see any changes you make to the copy of the struct fields. You will only see any changes to elements of the underlying array.


    In your case, you overwrite b (array, cap, len), a copy.

    b = []byte(result)
    

    The copy is is discarded when you return.


    What you want to do is change elements of b's array.

    For example,

    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

    Output:

    You cracked the code!
    

    The Go Blog: Go Slices: usage and internals

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 phython读取excel表格报错 ^7个 SyntaxError: invalid syntax 语句报错
  • ¥20 @microsoft/fetch-event-source 流式响应问题
  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?