与其他语言不同,为什么遍历字符串返回int32
值而不是原始字符?
例如:
func main() {
var s string
s = "Hello"
for _, v := range s {
fmt.Println(v)
}
}
返回:
72
101
108
108
111
我们应该使用如下所示的转换来获取原始字符吗?
func main() {
var s string
s = "Hello"
for _, v := range s {
fmt.Println(string(v))
}
}
答案 0 :(得分:7)
The Go Programming Language Specification
对于带有范围子句的语句
对于字符串值,“ range”子句遍历Unicode代码 从字节索引0开始的字符串中的点。连续 迭代,索引值将是的第一个字节的索引 字符串中连续的UTF-8编码的代码点,第二个 符文类型的值将是相应代码的值 点。如果迭代遇到无效的UTF-8序列,则 第二个值将是0xFFFD,Unicode替换字符,以及 下一次迭代将在字符串中前进单个字节。
在Go中,字符是Unicode代码点,是Go类型rune
(int32
的别名)。 Go string
用于以UTF-8编码形式存储Unicode代码点。
The Go Programming Language Specification
与字符串类型之间的转换
将有符号或无符号整数值转换为字符串类型会产生 包含整数的UTF-8表示形式的字符串。价值观 有效Unicode代码点范围之外的值将转换为 “ \ uFFFD”。
string('a') // "a" string(-1) // "\ufffd" == "\xef\xbf\xbd" string(0xf8) // "\u00f8" == "ø" == "\xc3\xb8" type MyString string MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5"
例如,
package main
import (
"fmt"
)
func main() {
helloworld := "Hello, 世界"
fmt.Println(helloworld)
for i, r := range helloworld {
fmt.Println(i, r, string(r))
}
}
游乐场:https://play.golang.org/p/R5sBeGiJzR4
输出:
Hello, 世界
0 72 H
1 101 e
2 108 l
3 108 l
4 111 o
5 44 ,
6 32
7 19990 世
10 30028 界
参考文献: