結論
- runeはGoにおける型の1種類
- rune型を用いることで、文字列を1文字づつ扱うことができる
前提知識
まず最初に文字コード(コードポインタ)や文字集合と符号化方式について理解しましょう。
こちらの記事にまとめておきました。
Golangにおける文字の扱い
この記事で詳しく書かれていますが、以下のようなコードを実行すると227 129 130
が出力されます。
s := "あ" for i := 0; i < len(s); i++ { b := s[i] // byte fmt.Println(b) } 出力: 227 129 130
直感で考えたり、他の言語だったりするとあ
と表示されるので違和感があると思います。
GoではString型に対してSliceでアクセスを行うと、その文字が格納されているByte値を出力します。
s := "あ" for i := 0; i < len(s); i++ { b := s[i] // byte fmt.Printf("%x\n", b) } 出力: e3 81 82
このように%x
をつけて16進数で表示するようにすると、UTF-8で表現されたあという文字が出力されることがわかりやすいと思います。
つまりまとめると、あいうえおみたいな文字列を1文字ごとにループで回すような処理をするときにSliceでIndexアクセスをさせると予想に反してバイト値へのアクセスになってしまうということです。
runeについて
これを回避するために使えるのがrune型です。range
をつかってループを回すことで変数r
にはrune型の値が入ります。
s = "あいうえお" for _, r := range s { // rune fmt.Println(r) } 出力: 12354 12356 12358 12360 12362
しかしrune型は対象の文字列のコードポイントを表示するものになるので、「あ」とか「い」が表示されるわけではなくその文字に割り当てられている数字が表示されます。
ややこしいことに、このとき表示される数字は「Unicodeの番号を10進数に変換したもの」です。例えば「あ」のUnicode番号は「U+3042」で、これを10進数表記に変更すると「12354」になります。
rune型の数字を元の文字に戻すにはstring()
を使ってあげましょう。
するとこのように出力することができます。
fmt.Println("---") for _, r := range s { // rune fmt.Println(string(r)) } 出力: あ い う え お
ということでここまでがrune型の説明でした!