【golang】rune,byteの浅い分析


【golang】rune,byteの浅い分析


golang内蔵タイプにはruneタイプとbyteタイプがあります.
runeタイプの下位タイプはint 32タイプであり、byteタイプの下位タイプはint 8タイプであることが知られており、これはruneがbyteより多くの数を表現できることを決定している.
unicodeでは、1つの中国語が2バイト、utf-8の1つの中国語が3バイト、golangのデフォルトの符号化がutf-8符号化であるため、デフォルトの1つの中国語が3バイトを占めているが、golangの文字列の最下位は実際にbyte配列である.そのため、次のような奇妙な状況が発生する可能性があります.
str := "hello  "
fmt.Println(len(str)) //12

golangのstring下位層はbyte配列によって実現され、golangのデフォルトの符号化はutf-8であるため、ここでは1つの中文文字が3バイトを占めるため、得られる長さは12であり、私たちが望む結果を得るのも簡単であり、golangのunicode/utf 8パッケージはutf-8で長さを取得する方法を提供している.
str := "hello  "
fmt.Println(utf8.RuneCountInString(str)) //8

byteタイプは実際にはint 8タイプであり、int 8はascii符号化文字を表現するのに適しているが、int 32はより多くの数を表現することができ、unicode文字をより容易に処理することができるので、runeタイプでunicode文字を処理することができる.
str := "hello  "
str2 := []rune(str)
fmt.Println(len(str2)) //8

ここではメモリを申請し、strの内容をこのメモリにコピーします.実際にはruneタイプのスライスですが、str 2はruneタイプのスライスの参照を取得しています.これは参照であることを簡単に証明できます.
str := "hello  "
str2 := []rune(str)
t := str2
t[0] = 'w'
fmt.Println(string(str2)) //“wello  ”

str 2をt,tに付与することで変化するデータは,実際にはtが指すruneスライスを変化させるため,strも変化する.

文字列の遍歴


文字列については、どのように遍歴するかを見てみましょう.遍歴は簡単かもしれませんが、golangに触れたばかりのとき、このように文字列を遍歴すると、非常に悪いことになります.
str := "hello  "

for i := 0;i < len(str);i++ {
    fmt.Println(string(str[i]))
}

出力:
h
e
l
l
o

ä
¸
ç

どうやってこの問題を解決しますか?
最初の解決策はrangeサイクルで
str := "hello  "

for _,v := range str {
    fmt.Println(string(v))
}

しゅつりょく
h
e
l
l
o

 

なぜならrangeは暗黙的なunicode復号化を行うからです
2つ目の方法はstrをruneタイプのスライスに変換することであり,この方法は既に述べたが,ここでは後述しない.
もちろん、その本質はbyteをruneに頼る方法もたくさんあります.

runeとbyteの違い


runeとbyteの下位層のタイプの違いを除いて、使用上、runeはすべての文字を処理することができて、byteはasciiに限られています