hakeの日記

Windows環境でプログラミングの勉強をしています。

Go言語 - 日本語文字列の操作

stringはバイト列なので、日本語文字列をインデックス指定で取り出しても文字単位の指定とはならない。文字単位で指定する場合には一旦runeのスライスに変換すると、インデックスが文字単位と一致する。
また、rangeを使用したforの中でも文字単位(rune)で取り出せる。

package main

import (
	"fmt"
)

func main() {

	var s string = "あaいbうc"

	// stringのスライスはバイト単位
	fmt.Println(s[:3])         //-> あ
	fmt.Printf("%x\n", s[:3])  //-> e38182
	fmt.Println(s[:4])         //-> あa
	fmt.Printf("%x\n", s[:4])  //-> e3818261


	// stringを一旦runeのスライスに変換して操作する。
	rs := []rune(s)
	fmt.Println(string(rs[:2]))    //-> あa


	// for文もインデックス指定はバイト単位
	for i := 0; i < len(s); i++ {
		fmt.Printf("%T\n", s[i])   //-> uint8(byteはuint8のエイリアス)
		fmt.Println(s[i])          //-> 227,……
	}

	// rangeで取り出すとrune単位で取り出せる。
	for _, c := range s {
		fmt.Printf("%T\n", c)   //-> int32(runeはint32のエイリアス)
		fmt.Println(string(c))  //-> あ,……
	}
}