摘要
go字符串結(jié)構(gòu)體包含:指向底層存儲數(shù)組的指針、字符串長度。字符串按utf-8將字符編碼成二進(jìn)制數(shù),然后存儲在byte數(shù)組中。因?yàn)閡tf-8編碼一個字符可能占用多個字節(jié),例如一個漢字占3個字節(jié),所以字符串中的一個字符可能對應(yīng)byte數(shù)組中的多個元素。為了讓一個字符對應(yīng)數(shù)組的一個元素以便于處理,go設(shè)計(jì)了rune類型,其底層是int32,四個字節(jié),正好能存儲最大四個字節(jié)utf-8編碼數(shù)據(jù)。
1、byte和rune類型
- byte等價于uint8類型的數(shù)據(jù),一個字節(jié)大小,是字符串底層存儲數(shù)據(jù)的結(jié)構(gòu)。
- rune等價于int32類型的數(shù)據(jù),四個字節(jié)大小,為了處理utf-8字符串而設(shè)計(jì)的。因?yàn)間o語言字符串默認(rèn)是按照utf-8編碼的方式存儲數(shù)據(jù)的,其中最大的字符占用4個字節(jié)的數(shù)據(jù),所以需要rune才能一個字符對應(yīng)一個數(shù)據(jù)元素。
2、字符串(string)
在go中字符串具有如下特征:
- go字符串存儲在只讀內(nèi)存段中,不能被修改,但可以被切片和復(fù)制。
- 字符串結(jié)構(gòu)由一個指向底層數(shù)組的指針和字符串長度組成。因?yàn)榻o出了具體長度,所以不需要以’\0’的方式判斷字符串結(jié)尾。
- 底層使用字節(jié)(byte)數(shù)組存儲字符串中各字符對應(yīng)的數(shù)字編碼。一個字符可能占用好幾個byte。
需要注意的是在utf-8編碼中,一個漢字占用3個字節(jié),而byte是uint8類型,一個byte元素一個字節(jié),需要三個byte才能存儲一個漢字。所以:
func main() {
s := "哈嘍世界"
fmt.Println(len(s)) // 輸出:12
}
而rune是int32類型,四個字節(jié),和utf-8最大字節(jié)數(shù)(4個字節(jié))一致,所以可以將string類型轉(zhuǎn)換為rune,去查看其具體存儲的字符數(shù)。如下:
func main() {
s := "哈嘍世界"
fmt.Println(len([]rune(s))) // 輸出:4
}
需要注意的是:go中rune類型就是為了處理utf-8字符串而設(shè)計(jì)的,而定長4字節(jié)的方式存儲utf-8中只占1、2、3個字節(jié)的字符,存在一定的空間浪費(fèi)。所以string默認(rèn)是按照byte類型的存儲的,更加節(jié)省空間,當(dāng)需要的時候,再轉(zhuǎn)換為rune處理。
3、練習(xí)-反轉(zhuǎn)字符串
如果反轉(zhuǎn)函數(shù)如下:
func reverse(s string) string {
bs := []byte(s)
sLen := len(bs)
for i := 0; i < sLen/2; i++ {
bs[i], bs[sLen-i-1] = bs[sLen-i-1], bs[i]
}
return string(bs)
}
那么傳入屬于1字節(jié)編碼的ASCILL字符,能夠被反轉(zhuǎn):
func main() {
s := "abcdefg"
fmt.Println(reverse(s)) // 輸出gfedcba
}
但是若傳入需要占用多個字節(jié)的字符,就會輸出亂碼:文章來源:http://www.zghlxwxcb.cn/news/detail-493945.html
s := "哈嘍世界"
fmt.Println(reverse(s)) // 輸出??疸佖刓?
所以如果想要使得所有輸入字符都能被正確的反轉(zhuǎn),應(yīng)該使用rune代替byte:文章來源地址http://www.zghlxwxcb.cn/news/detail-493945.html
func reverse(s string) string {
bs := []rune(s)
sLen := len(bs)
for i := 0; i < sLen/2; i++ {
bs[i], bs[sLen-i-1] = bs[sLen-i-1], bs[i]
}
return string(bs)
}
func main() {
s := "哈嘍世界"
fmt.Println(reverse(s)) // 輸出:界世嘍哈
}
到了這里,關(guān)于go字符串詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!