Ответ
Для корректного подсчета символов (рун) в строке, особенно если она содержит кириллицу или другие многобайтовые символы (например, emoji), необходимо использовать пакет unicode/utf8
.
Почему len()
не подходит?
В Go строка — это последовательность байт. Встроенная функция len()
возвращает именно количество байт, а не символов. Поскольку символы в кодировке UTF-8 могут занимать от 1 до 4 байт, len()
даст неверный результат для не-ASCII строк.
len("abc")
вернет3
(3 символа, 3 байта).len("Привет")
вернет12
(6 символов, 12 байт, т.к. каждая буква кириллицы занимает 2 байта).
Правильный способ: utf8.RuneCountInString()
Эта функция специально предназначена для подсчета рун (кодовых точек Unicode) в строке.
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Привет, мир! 👋"
// Неправильный способ
fmt.Printf("Количество байт (len): %dn", len(s))
// Правильный способ
fmt.Printf("Количество символов (рун): %dn", utf8.RuneCountInString(s))
}
// Вывод:
// Количество байт (len): 21
// Количество символов (рун): 15
Итерация по строке
Для перебора символов строки также следует использовать конструкцию for ... range
. Она автоматически декодирует UTF-8 символы в руны.
for index, r := range "Привет" {
// index - начальная позиция байта руны
// r - сама руна (тип rune, который является псевдонимом для int32)
fmt.Printf("индекс: %d, символ: %cn", index, r)
}