根据https://blog.golang.org/strings和我的测试,看起来当我们range
一个字符串时,我们得到的字符是rune
种,但是如果我们到str[index]
得到它,他们就会是byte
种,为什么呢?
根据https://blog.golang.org/strings和我的测试,看起来当我们range
一个字符串时,我们得到的字符是rune
种,但是如果我们到str[index]
得到它,他们就会是byte
种,为什么呢?
对于第一个层次,why是因为这是how the language is defined.String type告诉我们:
字符串值是(可能为空的)字节序列.字节数称为字符串的长度,从不为负数.字符串是不可变的:一旦创建,就不可能更改字符串的内容.
以及:
字符串的字节可以通过整数索引0到len(s)-1访问.
同时,range
是一个可以插入到for
statement中的子句,说明书上写着:
"Range"子句右边的表达式称为range expression,它可能是…[A]字符串.
以及:
- 对于字符串值,"range"子句迭代字符串中从字节索引0开始的Unicode代码点.在连续迭代中,索引值将是字符串中连续UTF-8编码代码点的第一个字节的索引,第二个
rune
类型的值将是相应代码点的值.如果迭代遇到无效的UTF-8序列,第二个值将是0xFFFD
,Unicode替换字符,下一次迭代将在字符串中前进一个字节.
如果你想知道为什么语言是这样定义的,你真的必须问问定义者自己.然而,请注意,如果for
只在字节范围内,那么你需要构建自己的更奇特的循环来覆盖符文.假设for ... range
does处理符文,如果want处理字符串s
中的字节,则可以编写:
for i := 0; i < len(s); i++ {
...
}
并且容易地在循环内访问s[i]
.您还可以编写:
for i, b := range []byte(s) {
}
并且访问循环内的索引i
和字节b
.(从字符串到[]byte
的转换或从字符串到[]byte
的转换可能需要副本,因为[]byte
可以修改.不过,在这种情况下,range
不会修改它,编译器可以优化掉副本.请参见smidgen584610_58635831">icza's comment below或this answer至golang: []byte(string) vs []byte(*string).)所以你没有失go 任何能力,也许只是smidgen的简洁性.