🚀

Golangでbyte表現と、ASCIIに少し詳しくなった話

2024/07/03に公開

golangでstringとbyte間で勝手に変換される「あれ」について、「あれ」というよりはマシな解像度で理解できる様にまとめました。

tl:dr

  • Golangの言語仕様から、stringとbyteの話をするよ
  • 筆者は文字コード周りについて詳しくなかったので、その辺が学びになったよ
  • byte表現することで何が嬉しいの?に関する話はしてないよ

Golangはstringをbyteシーケンスとして表現する

下記は、ハードコードしたstringから一文字目を抽出しようとしたコードです。

import "fmt"

func main() {
    original := "aaabbbcccaaa"

	result := original[0]
	fmt.Println("result: ", result)
}
出力
char:  97

あれ、aという出力が欲しかったな
97? ...とscript言語ユーザーの方は思ったはずです。
次にいきましょう

Golangのstringについて

先程のケース、例えばtypescriptならaに当たるstringの最初の要素を返してくれますよね。

const fetch = () => {
    const text = "aaabbbcccaaa"
    const result = text[0]
    return result
}

console.log(fetch())
出力
a

なぜgolangでの出力は97だったか。答えは簡単です。
golangでは、stringの要素はbyteのシーケンスをUFT-8 Encodeした結果として表現しています

  • シーケンス
    • 一連のデータのまとまり。 aaabbbcccaaaとか
  • UFT-8

byte

次に、byteについて見ていきます。
厳密な定義かは怪しいですが「通常8ビットから構成され、0から255までの整数値を表現する」ものであると言って、違う!とはならないでしょう。

golangの話に戻します。

stringの要素はbyteのシーケンスをUFT-8 Encodeした結果として表現しています

という話がありましたが、逆も然りです。
string(UFT-8)から特定要素を抽出すると、その結果はbyteとして表現されます
更にいうとbyteとはADCIIで表現されています。
link先の表を見ると、a = 97として ADCIIで規定されていますね。
これが先程の出力97の原因であり答えです。

UFT-8, byte, binary

今回のa97の変換とは別で、binaryの世界もありますね。

Character: a
ASCII Value: 97
Binary Value: 01100001

こうなると機械が解釈できるデータになります。
流れを追って見ていくと、普段見ているソースコードから機械語への変換が少し身近に感じられますね。Golangの好きな所。

Discussion