在 Go 语言里,len
函数在处理字符串时,返回的是字符串所占用的字节数,而非字符的数量。这一差异在处理包含多字节字符(像 UTF - 8 编码的中文、日文、韩文等字符)时尤为明显。
UTF - 8 编码规则
UTF - 8 是一种变长编码,不同字符占用的字节数有所不同:
- 对于 ASCII 字符(如英文字母、数字和常见标点符号),每个字符占 1 个字节。
- 对于大多数常见的汉字,每个字符占 3 个字节。
- 某些特殊字符或表情符号可能占 4 个字节。
示例代码分析
以下代码展示了 len
函数对不同字符串的处理结果:
package main
import (
"fmt"
)
func main() {
// 包含 5 个 ASCII 字符的字符串
asciiStr := "abcde"
fmt.Printf("ASCII 字符串: %s, 长度: %d\n", asciiStr, len(asciiStr))
// 包含 5 个汉字的字符串
chineseStr := "测试数据!"
fmt.Printf("中文 字符串: %s, 长度: %d\n", chineseStr, len(chineseStr))
}
代码解释
- ASCII 字符串:
asciiStr
由 5 个 ASCII 字符构成,每个字符占 1 个字节,所以len(asciiStr)
的结果是 5。 - 中文 字符串:
chineseStr
包含 5 个汉字和 1 个标点符号,每个汉字通常占 3 个字节,标点符号可能占 1 或 3 个字节(取决于具体编码),所以len(chineseStr)
的结果会大于 5。
获取字符数量的方法
若要获取字符串中字符的实际数量,可将字符串转换为 rune
切片,再计算切片的长度,示例如下:
package main
import (
"fmt"
)
func main() {
chineseStr := "测试数据!"
runeSlice := []rune(chineseStr)
charCount := len(runeSlice)
fmt.Printf("中文 字符串: %s, 字符数量: %d\n", chineseStr, charCount)
}
总结
len
函数返回的是字符串占用的字节数,而非字符数量。在处理多字节字符时,要把字符串转换为 rune
切片来获取准确的字符数量。若输入的 5 个字符是多字节字符,len
函数返回 15 是合理的,因为每个字符可能占 3 个字节。