Ответ
В Go строка — это последовательность байт. Поэтому прямое использование len(str)
вернет количество байт, а не символов (рун), что некорректно для многобайтовых кодировок, таких как кириллица или эмодзи.
Правильный способ: utf8.RuneCountInString
Самый эффективный способ — использовать функцию RuneCountInString
из пакета unicode/utf8
. Она итерируется по строке, подсчитывая валидные UTF-8 символы (руны).
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "Привет, мир! 👋"
// Неправильно: подсчет байт
byteCount := len(str)
// Правильно: подсчет символов (рун)
runeCount := utf8.RuneCountInString(str)
fmt.Printf("Строка: %sn", str)
fmt.Printf("Количество байт: %dn", byteCount) // Выведет: 26
fmt.Printf("Количество символов: %dn", runeCount) // Выведет: 15
}
Альтернативный способ: конвертация в []rune
Можно преобразовать строку в срез рун и затем получить его длину с помощью len()
.
str := "Привет, мир! 👋"
runeSlice := []rune(str)
fmt.Println(len(runeSlice)) // Выведет: 15
Сравнение способов:
utf8.RuneCountInString(str)
: Более эффективен по памяти. Он не создает новую копию данных, а только итерируется по существующей строке.len([]rune(str))
: Проще для написания, но создает новую копию данных в виде слайса рун, что приводит к дополнительному выделению памяти. Этот способ стоит использовать, если вам в дальнейшем нужен сам срез рун для других операций (например, для изменения или доступа к символу по индексу).