JuniorКодИногдаЕщё не отвечали
Что выведут len(s) и utf8.RuneCountInString(s) для s := "héllo"?
Прочитайте фрагмент ниже. Строка "héllo" содержит многобайтовый символ UTF-8 é.
Определите, что выведут len(s) и utf8.RuneCountInString(s), и объясните, почему эти два числа различаются.
import "unicode/utf8"
s := "héllo"
fmt.Println(len(s), utf8.RuneCountInString(s))
Определите вывод.
Выведет 6 5. len(s) считает байты, а é занимает два байта в UTF-8, поэтому длина в байтах равна 6, а число рун (символов) — 5. Проход for i, r := range s итерирует руны, тогда как индексация s[i] возвращает один байт, а не символ.
- ✗Считать, что
len(s)возвращает число символов — он возвращает число байтов - ✗Думать, что
s[i]индексирует руны; он индексирует байты - ✗Забывать, что многобайтовые символы UTF-8, как
é, занимают больше одного байта
- →Сколько итераций делает
for i, r := range sи каким будетiпослеé? - →Почему
[]rune(s)выделяет память, аrangeпо строке — нет?
Оглавление
Что выведет код?
import "unicode/utf8"
s := "héllo"
fmt.Println(len(s), utf8.RuneCountInString(s))
Вывод
6 5
Байты против рун
Строка в Go — это неизменяемая последовательность байтов в кодировке UTF-8, а не последовательность символов.
len(s)возвращает число байтов. Латинскоеé(U+00E9) в UTF-8 занимает два байта (0xC3 0xA9), аh,l,l,o— по одному. Итого2 + 1*4 = 6.utf8.RuneCountInString(s)декодирует байты в руны (кодовые точки) и считает их:h é l l o=5.
Отсюда два следствия при работе со строками:
for i, r := range s { /* r — руна, i — байтовый индекс начала руны */ }
b := s[1] // байт 0xC3 — половина 'é', НЕ символ
⚠️ Индексация s[i] даёт байт; чтобы работать с символами, итерируйте через range или приводите к []rune(s) (с аллокацией).
Оглавление