Как правильно посчитать количество символов в строке?

Ответ

В 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)): Проще для написания, но создает новую копию данных в виде слайса рун, что приводит к дополнительному выделению памяти. Этот способ стоит использовать, если вам в дальнейшем нужен сам срез рун для других операций (например, для изменения или доступа к символу по индексу).