1、字符編碼
(1)ASCII碼
一個字節表示的英文、數字、標點符號等字符。
國際標准ASCII碼為0-127即128個字符,二進制最高位為0,其余為擴展ASCII碼。
(2)GB2312
兩字節,主要包含簡體的常用中文及符號的字符集編碼。
(3)GBK
單雙字節變長編碼,主要包含簡體與繁體中文和一些符號、偏旁部首的字符集編碼。
(4)GB18030
GBK編碼無法滿足需求擴展,多出來的部分使用四字節編碼,即單、雙、四字節編碼;
擴展了漢字,還包括了少數民族文字;
(5)Unicode
因各國語言、字符差異,Unicode將所有字符統一為一套字符集。
UTF-8、UTF-16、UTF-32是對Unicode字符集的不同編碼方案。
(6)UTF-8
變長編碼方式,1-4字節表示一個字符,可節省存儲空間;
英文1字節,中文一般3字節,最多4字節;
編碼規則:
》單字節:同標准ASCII碼,最高位為0,0-127表示128個字符
》多字節:n字節,高位到低位,第一字節前n位為1,第n+1位為0;后面字節前兩位為10;剩余位由低位向高位填補Unicode嗎,多出補0;
110XXXXX 10XXXXXX
1110XXXX 10XXXXXX 10XXXXXX
2、字符串遍歷
golang使用utf-8的編碼方式
2.1、for循環遍歷字符串
func main() { str := "test篤志弘毅" for i := 0; i < len(str); i++ { fmt.Printf("%v %c,", str[i], str[i]) } } //116 t,101 e,115 s,116 t,231 ç,172 ¬,131 ,229 å,191 ¿,151 ,229 å,188 ¼,152 ,230 æ,175 ¯,133 ,
以下標訪問字符串時,按單字節(byte)訪問,超出單字節的編碼會出現亂碼。
2.2、for range遍歷字符串
func main() { str := "test篤志弘毅" for i, v := range str { fmt.Printf("%d-%c-%v ", i, v, v) } } //0-t-116 1-e-101 2-s-115 3-t-116 4-篤-31491 7-志-24535 10-弘-24344 13-毅-27589
for range遍歷字符串時,按字符(rune)訪問,中文正常顯示
3、字符串轉字符切片和字節切片的差異
func main() { str := "test篤志弘毅" runeS := []rune(str) for i := 0; i < len(runeS); i++ { fmt.Printf("%c-%v ", runeS[i], runeS[i]) } fmt.Println() byteS := []byte(str) for i := 0; i < len(byteS); i++ { fmt.Printf("%c-%v ", byteS[i], byteS[i]) } } //t-116 e-101 s-115 t-116 篤-31491 志-24535 弘-24344 毅-27589 //t-116 e-101 s-115 t-116 ç-231 ¬-172 -131 å-229 ¿-191 -151 å-229 ¼-188 -152 æ-230 ¯-175 -133
4、字符串注意點
(1)字符串的零值為空串"",不是nil
func main() { var str string fmt.Println(str == "") //true //fmt.Println(str == nil) //invalid operation: str == nil (mismatched types string and nil) //無效操作(string和nil類型不匹配) }
(2)索引訪問或是切片得到的都是按字節處理,可能出現亂碼
(3)len函數返回的是字節數,而不是字符數
func main() { str := "test篤志弘毅" fmt.Println(len(str))//16 }
(4)不能通過索引或指針修改字符串字符
func main() { str := "test篤志弘毅" str[2] = 'a' //cannot assign to str[2] *(&str[2]) = 'b' // cannot take the address of str[2] fmt.Println(str) }
(5)字符串的切片操作返回的是字符串,而不是切片
func main() { str := "test篤志弘毅" str1 := str[:] str2 := str[:] fmt.Printf("%T %p %p\n", str1, &str1, &str2) } //string 0xc0000581c0 0xc0000581d0