Go言語で文字列のエンコーディングを理解!UTF-8の基本を初心者向けに解説
生徒
「Go言語で文字列を扱うとき、エンコーディングって何ですか?」
先生
「エンコーディングとは、文字をコンピュータが理解できる数字の形に変換するルールのことです。Go言語では基本的にUTF-8という方式を使っています。」
生徒
「UTF-8って聞いたことあります。具体的にはどんなものなんですか?」
先生
「UTF-8は、世界中のほとんどの文字を表現できる方式で、1文字が1〜4バイトで表されます。ASCII文字は1バイト、日本語などの文字は複数バイトで表現されます。」
生徒
「なるほど!Goで文字列を扱うときは、いつもUTF-8で保存されているんですね?」
先生
「その通りです。UTF-8を理解すると、文字列操作やバイトスライスの扱い方もより理解しやすくなります。」
1. Go言語の文字列はUTF-8で保存される
Go言語の文字列は、内部的にUTF-8で保存されます。UTF-8は可変長のエンコーディング方式で、英数字は1バイト、日本語などのマルチバイト文字は2〜4バイトで表現されます。この仕組みを理解すると、文字列の長さや文字単位の操作が重要であることがわかります。
2. 文字列の長さとバイト数の違い
UTF-8では、文字列の長さとバイト数は一致しないことがあります。英語の文字は1バイト、日本語の文字は3バイト程度になることが多いです。そのため、len()関数で取得できるのはバイト数で、文字数ではありません。
package main
import (
"fmt"
)
func main() {
str := "Go言語"
fmt.Println("バイト数:", len(str))
}
バイト数: 8
上記の例では、日本語2文字と英字1文字で構成されていますが、バイト数は8になります。これはUTF-8で日本語1文字が3バイトで表現されるためです。
3. 文字単位で扱うにはrune型を使う
文字単位で操作したい場合、Goではrune型を使います。runeはUnicodeコードポイントを表す型で、1文字ごとに扱うことができます。
package main
import (
"fmt"
)
func main() {
str := "Go言語"
for i, r := range str {
fmt.Printf("インデックス %d: %c\n", i, r)
}
}
インデックス 0: G
インデックス 1: o
インデックス 3: 言
インデックス 6: 語
インデックスがバイト単位で表示されることに注意してください。runeを使うと、文字単位で正確に処理できます。
4. バイトスライスとの関係
文字列をバイトスライスに変換すると、UTF-8でエンコードされたバイト列として扱えます。バイト単位での処理や、ファイルへの書き込み、ネットワーク通信などに便利です。
package main
import (
"fmt"
)
func main() {
str := "Go言語"
b := []byte(str)
fmt.Println(b)
}
[71 111 230 149 136 232 170 158]
英字は1バイト、日本語はUTF-8で3バイトずつに変換されていることがわかります。
5. まとめると
Go言語では文字列はUTF-8で保存され、len()で取得できるのはバイト数です。文字単位で操作する場合はrune型を使い、バイト単位で処理する場合は[]byte型を使用します。UTF-8の仕組みを理解すると、日本語や特殊文字を含む文字列の操作も安全に行えます。