ふわっとテック日記

テック系のことをメインに書いていきます。go言語/typescript/javascriptが好きです。たまに趣味(筋トレ)の話や日常系の記事も書きたいな〜と思っています。

go言語での文字列変換

go言語での文字列の他データ型への変換についてさらっと書きます。

こちらの公式ドキュメントに言及、一部和訳しています。

go.dev


go言語の文字列(string型)は、rune型のスライス(rune)とbyte型のスライス(byte)にそれぞれ変換可能です。


rune型の実態はint32で、Unicodeのコードポイントを10進数表記で表します。

// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32

下記のように for range で文字列を繰り返し処理にかけると、rune型で一文字ずつ取得できます。

str := "あいうえお"
for _, s := range str {
    fmt.Printf("Type: %s, Value: %d\n", reflect.TypeOf(s), s)
}

/* OUTPUT:
Type: int32, Value: 12354
Type: int32, Value: 12356
Type: int32, Value: 12358
Type: int32, Value: 12360
Type: int32, Value: 12362
*/

Unicode文字一覧表 - instant tools

各文字の出力がUnicodeのコードポイントの数値に合致していることがわかります。



またbyte型の実態はuint8で、1バイトを10進数表記で表します。

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8

下記のように for 初期値; 条件; 変化式 で文字列を繰り返し処理にかけると、byte型で1バイトごとに取得できます。

str := "あいうえお"
for i := 0; i < len(str); i++ {
    fmt.Printf("Type: %s, Value: %d\n", reflect.TypeOf(str[i]), str[i])
}

/* OUTPUT:
Type: uint8, Value: 227
Type: uint8, Value: 129
Type: uint8, Value: 130
Type: uint8, Value: 227
Type: uint8, Value: 129
Type: uint8, Value: 132
Type: uint8, Value: 227
Type: uint8, Value: 129
Type: uint8, Value: 134
Type: uint8, Value: 227
Type: uint8, Value: 129
Type: uint8, Value: 136
Type: uint8, Value: 227
Type: uint8, Value: 129
Type: uint8, Value: 138
*/

このケースではバイトごとの繰り返しになるため、日本語のようなマルチバイト文字だと1文字ずつ抜き出せないことに注意してください。

rune型の場合はUnicodeコードポイントで1文字ごとに対応しているため、string(value)で文字列に変換できます。


数値をstring変換した場合は、その数値に対応するUnicodeコードポイントの文字に変換されます。 コードポイント範囲外の数値の場合は \ufffd に変換されます。

num1 := 12450
fmt.Println(string(num1))

/* OUTPUT:

*/

stringを介さずにruneとbyteを変換する場合はunicode/utf8パッケージのEncodeRuneDecodeRuneなどが使えるかと思います。

pkg.go.dev


余談ですが、公式ドキュメントのコード例に元横綱白鵬翔を発見しました。 ちょっと嬉しかったです。