← Назад к вопросам

Что показывает len для строки?

2.2 Middle🔥 101 комментариев
#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что возвращает len() для строки в Go?

Функция len(), применяемая к строке (string) в языке Go, возвращает количество байтов (bytes) в этой строке, а не количество символов (unicode characters).

Это принципиально важное отличие, которое связано с внутренним представлением строк в Go. Строки в Go — это последовательности байтов, представляющие текст в кодировке UTF-8. Поскольку UTF-8 является многобайтовой кодировкой, один символ (например, кириллическая буква или эмодзи) может занимать более одного байта.

Примеры и объяснение

Рассмотрим простой пример с латинскими символами:

package main

import "fmt"

func main() {
    str := "Hello"
    fmt.Println(len(str)) // Вывод: 5
}

Здесь каждый символ занимает 1 байт, поэтому len("Hello") возвращает 5.

А теперь пример с символом, который занимает более одного байта в UTF-8:

package main

import "fmt"

func main() {
    str := "Привет"
    fmt.Println(len(str)) // Вывод: 12
}

Слово "Привет" содержит 6 символов, но функция len() возвращает 12. Это потому что каждый кириллический символ в UTF-8 кодируется 2 байтами. Следовательно, 6 символов * 2 байта = 12 байтов.

Ещё более яркий пример — использование символов, занимающих 3 или 4 байта:

package main

import "fmt"

func main() {
    emoji := "😀"
    fmt.Println(len(emoji)) // Вывод: 4
}

Эмодзи "😀" является одним символом, но в UTF-8 он занимает 4 байта, поэтому len() возвращает 4.

Почему это важно и как получить количество символов?

Функция len() отражает низкоуровневое представление данных и часто используется для операций с самими байтами (например, при работе с сетью, файлами или криптографией). Однако для логики, связанной непосредственно с текстом (подсчёт символов, ограничение длины текста для пользователя, разбиение на слова), требуется работать с символами (рунами).

Для получения количества символов (unicode code points) в строке необходимо преобразовать строку в последовательность рун ([]rune) и взять её длину, либо использовать функцию utf8.RuneCountInString() из стандартной библиотеки.

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    str := "Привет 😀"

    // Способ 1: преобразование в []rune
    runes := []rune(str)
    fmt.Println("Количество символов (рун):", len(runes)) // Вывод: 8

    // Способ 2: использование utf8.RuneCountInString
    fmt.Println("Количество символов (utf8):", utf8.RuneCountInString(str)) // Вывод: 8
}

В этом примере строка "Привет 😀" содержит 6 кириллических символов (2 байта каждый) и один эмодзи (4 байта), что в сумме составляет 12 байтов. Однако количество символов равно 7. Если в строке есть пробел (1 байт), общее количество символов становится 8, как показано в выводе.

Ключевые выводы

  • len(string) возвращает число байтов, а не символов.
  • Это поведение прямо связано с тем, что строки в Go — это байтовые последовательности в UTF-8.
  • Для подсчета символов используйте utf8.RuneCountInString() или преобразуйте строку в []rune.
  • Понимание этой разницы критично для корректной обработки текста, особенно многобайтового (не-ASCII), и для избегания ошибок в логике, связанной с длиной строки.
Что показывает len для строки? | PrepBro