package main
import "fmt"
func printBytes(s string) {
for i := 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
}
现在我们将前面这段代码修改如下:
package main
import "fmt"
func printBytes(s string) {
for i := 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func printChars(s string) {
for i := 0; i < len(s); i++ {
fmt.Printf("%c ", s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Println()
printChars(name)
}
48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
这里使用%c来打印字符串中的每个字符看起来是合法的,但其实是有问题的。我们换个字符串来打印试试看:
package main
import "fmt"
func printBytes(s string) {
for i := 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func printChars(s string) {
for i := 0; i < len(s); i++ {
fmt.Printf("%c ", s[i])
}
}
func main() {
name := "Señor"
printBytes(name)
fmt.Println()
printChars(name)
}
53 65 c3 b1 6f 72
S e à ± o r
这里我们本来期望打印出Señor,却打印出了S e à ± o r。你肯定会疑惑,为什么打印Hello World能正常打印,换成Señor却不行。其实我们应该能看出来,这里是字符ñ打印成了à ±。为什么会这样呢?是因为字符ñ对应的Unicode码点为U+00F1,采用UTF-8编码会占用两个字节:c3和b1,而前面程序中直接按照%c格式打印字符串是按照每个字符一个字节来打印的,因此才打印出了错误的结果。那怎么避免这种bug呢?Golang提供了rune(符文)数据类型来解决这个问题。