1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

go-tourの#61を解いてみる

Last updated at Posted at 2014-08-27

問題

概要

  • 文字列入力ストリームをメンバ変数に持っている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初心者なので、ここがバグっているとかもっとスマートなやり方とかがありましたらどしどしお願いします。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?