(感觉上面的答案仍然没有很清楚地说明字符串和[]符文之间的区别和关系,所以我会尝试用一个例子来补充另一个答案。)
正如@Strangework的回答所说,字符串和[]符文是完全不同的。
区别-字符串和[]符文:
字符串值是只读字节片。并且,字符串文字用utf-8编码。字符串中的每个字符实际占用1 ~ 3个字节,而每个符文占用4个字节
对于string, len()和index都基于字节。
对于[]符文,len()和index都基于符文(或int32)。
关系-字符串和[]符文:
当您将字符串转换为[]符文时,该字符串中的每个utf-8字符都成为一个符文。
类似地,在反向转换中,当从[]符文转换为字符串时,每个符文都变成字符串中的utf-8字符。
小贴士:
你可以在字符串和[]符文之间转换,但它们在类型和整体大小上仍然是不同的。
(我将添加一个例子来更清楚地说明这一点。)
Code
string_rune_compare.go:
// string & rune compare,
package main
import "fmt"
// string & rune compare,
func stringAndRuneCompare() {
// string,
s := "hello你好"
fmt.Printf("%s, type: %T, len: %d\n", s, s, len(s))
fmt.Printf("s[%d]: %v, type: %T\n", 0, s[0], s[0])
li := len(s) - 1 // last index,
fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])
// []rune
rs := []rune(s)
fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}
func main() {
stringAndRuneCompare()
}
执行:
运行string_rune_compare.go
输出:
hello你好, type: string, len: 11
s[0]: 104, type: uint8
s[10]: 189, type: uint8
[104 101 108 108 111 20320 22909], type: []int32, len: 7
解释:
The string hello你好 has length 11, because the first 5 chars each take 1 byte only, while the last 2 Chinese chars each take 3 bytes.
Thus, total bytes = 5 * 1 + 2 * 3 = 11
Since len() on string is based on bytes, thus the first line printed len: 11
Since index on string is also based on bytes, thus the following 2 lines print values of type uint8 (since byte is an alias type of uint8, in go).
When converting the string to []rune, it found 7 utf8 chars, thus 7 runes.
Since len() on []rune is based on rune, thus the last line printed len: 7.
If you operate []rune via index, it will access base on rune.
Since each rune is from a utf8 char in the original string, thus you can also say both len() and index operation on []rune are based on utf8 chars.