Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что возвращает 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), и для избегания ошибок в логике, связанной с длиной строки.