Contents
文字を扱う型、byteとruneはどう違う?
Goでは文字を扱う型としてbyteとruneが、文字列を扱う型としてstringがあります。string型はUTF-8で符号化されたバイト列を保持し、[]byte(s)でバイト列へ変換できます。またruneはユニコードのコードポイントを格納し、[]rune(s)でコードポイント列へ変換できます。ソースコード上では””はstring型、”はrune型として扱われます。
(『みんなのGo言語』)
Go言語で定義されている文字を扱う型、byteとrune。バイト列?コードポイント?とクエスチョンだらけだったのですが、最近ちょっと腑に落ちました。
参考にした記事はこちら。自分なりに要約すると、runeが格納しているコードポイントとは、Unicodeの体系の中で、それぞれの文字に割り当てられたコンピューテーショナルな値のこと。これで何が嬉しいかというと、文字コードの歴史上、後から追加された多バイト文字(漢字・仮名など)も、ちゃんと一字ずつ取得できること。
package mainimport "fmt"func main() { en := "This is a pen."bytes_en := []byte(en) runes_en := []rune(en) fmt.Printf("English byte: %+v\n", string(bytes_en[1])) fmt.Printf("English rune: %+v\n", string(runes_en[1])) ja := "これはペンです" bytes_ja := []byte(ja) runes_ja := []rune(ja) fmt.Printf("Japanese byte: %+v\n", string(bytes_ja[1])) fmt.Printf("Japanese rune: %+v\n", string(runes_ja[1]))}// 出力結果// English byte: h// English rune: h// Japanese byte: // Japanese rune: れ
上のコードでは、アルファベット文字列および日本語文字列について、それぞれbyte, runeスライスをつくり、その2つ目の要素を出力しています。つまり、「文字列の2文字目を出力しよう」としています。が、単純なバイト列だと、多バイト文字である漢字・仮名は「文字の一部」しか出力できず文字化けしてしまいます。一方、rune型だと「ユーザが文字として認識するかたまり(正式には書記素 grapheme と呼ばれます)」を単位として情報が格納されるので、多バイト文字に起因する文字化けを防げる 、というワケです。
参考
- Goのruneを理解するためのUnicode知識
- Unicodeとは? その歴史と進化、開発者向け基礎知識
- 改訂2版 みんなのGo言語【電子書籍】[ 松木雅幸 ]
- プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL CO) [ アラン・A.A.ドノバン ]
【中古】プログラマのための文字コ-ド技術入門 /技術評論社/矢野啓介(単行本(ソフトカバー))価格:652円 (2021/12/15 07:30時点) |