Go的字符串遍歷,有兩種方式:
- utf-8遍歷
- unicode遍歷
package main import "fmt" func main() { str := "Hello,世界" fmt.Println("Utf-8遍歷") for i := 0; i < len(str); i++ { ch := str[i] fmt.Println(ch) } fmt.Println("Unicode遍歷") for _, ch1 := range str { fmt.Println(ch1) } }
打印結果:
Utf-8遍歷 72 101 108 108 111 44 228 184 150 231 149 140 Unicode遍歷 72 101 108 108 111 44 19990 30028
上面代碼執行后,會打印一串數字而不是字符。這是由於go語言中的字符串實際上是類型為byte的只讀切片。或者說一個字符串就是一堆字節。這意味着,當我們將字符存儲在字符串中時,實際存儲的是這個字符的字節。一個字符串包含了任意個byte,它並不限定Unicode,UTF-8或者任何其他預定義的編碼。
那么go語言用什么來表示字符呢,下面的例子可以驗證一下:
package main import ( "fmt" "reflect" ) func main() { str := "Hello,世界" fmt.Println("Utf-8遍歷") for i := 0; i < len(str); i++ { ch := str[i] ctype:=reflect.TypeOf(ch) fmt.Printf("%s ",ctype) } fmt.Println("Unicode遍歷") for _, ch1 := range str { ctype:=reflect.TypeOf(ch1) fmt.Printf("%s ",ctype) } }
打印結果:
Utf-8遍歷
uint8 uint8 uint8 uint8 uint8 uint8 uint8 uint8 uint8 uint8 uint8 uint8
Unicode遍歷
int32 int32 int32 int32 int32 int32 int32 int32
代碼運行后顯示ch的類型為uint8,也就是byte類型,而ch1的類型為int32,也就是rune類型。
go語言中的源碼定義為utf-8文本,不允許其他的表示。
但是也存在特殊處理,那就是字符串上使用for…range循環。
range循環迭代時,就會解碼一個utf-8編碼的rune。
現在既然已經知道上述不管哪種遍歷方式,其實質都是字節。
所以在打印時,只需要將這些結果轉化為字符字面值或者轉換其輸出類型就可以了。
下面是兩種字符串遍歷方式:
package main import ( "fmt" ) func main() { str := "Hello,世界" fmt.Println("方法一 格式化打印") for _, ch1 := range str { fmt.Printf("%q",ch1) //單引號圍繞的字符字面值,由go語法安全的轉義 } fmt.Println("方法二 轉化輸出格式") for _, ch2 := range str { fmt.Println(string(ch2)) } }
打印結果:
方法一 格式化打印 'H''e''l''l''o'',''世''界'
方法二 轉化輸出格式 H e l l o , 世 界