問題
概要
- 文字列入力ストリームをメンバ変数に持っているReader型を作る
- 読み込んだ文字列をROT13のアルゴリズムで変換して読み込む
回答
package main
import (
"bytes"
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (reader rot13Reader) Read(p []byte) (n int, err error) {
tmp1 := make([]byte, 10)
n, err = reader.r.Read(tmp1)
tmp2 := bytes.Map(func(r rune) rune {
switch {
case ('a' <= r && r <= 'z'):
return 'a' + (r-'a'+13)%26
case ('A' <= r && r <= 'Z'):
return 'A' + (r-'A'+13)%26
default:
return r
}
}, tmp1)
copy(p, tmp2)
return
}
func main() {
s := strings.NewReader(
"Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
説明
- byteスライス(配列みたいなもの)のtmp1に元となるreaderを読む
- tmp1の配列の初期化のときの要素数は10にしているが、0でなければ1を指定してもエラーが起こらなかった、何でだろう・・・?
- bytes.Mapは第2引数のbyteスライス(tmp1)をrune(Javaでいうcharみたいなもの)ごとに分割して最終的に第1引数の関数で返ってきたruneを順番に詰めたbyteスライス(tmp2)を返す
- ROT13のアルゴリズムはruneの値と剰余を使って実装
- Mapで渡している関数内でやってるswitch文はif-elseでも同じことが書ける
- http://go-tour-jp.appspot.com/#47
- 最後にMap関数で返ってきたtmp2をpにコピーして完成
ツッコミ募集中
筆者はgolang初心者なので、ここがバグっているとかもっとスマートなやり方とかがありましたらどしどしお願いします。