Перейти к содержимому
5 / 15

Строки, руны и байты: почему len не считает символы

Строка в Go — это неизменяемая последовательность байтов, а не символов, и по соглашению эти байты содержат UTF-8. Отсюда всё поведение. len(s) возвращает число байтов: у строки «Привет» оно равно 12, а не 6. Индексация s[0] даёт байт типа byte, а не символ. Зато for i, r := range s декодирует UTF-8 и отдаёт руны — кодовые точки типа rune, то есть int32, — причём i при этом байтовый индекс, а не порядковый номер символа. Отсюда правила: длину в символах считают через utf8.RuneCountInString, срезать по индексу можно только там, где границы заведомо байтовые, а для посимвольной работы строку превращают в []rune. И отдельная тонкость, о которой забывают: даже руна — не то же самое, что видимый символ; эмодзи с модификаторами и буквы с комбинирующими знаками занимают несколько рун.

Строки, руны и байты: почему len не считает символы | JScriptiser