Как в Go устроены строки, байты и руны?
- Почему len("привет") в Go равно 12?
- Как перебрать символы строки в Go?
Строка — неизменяемая последовательность байт, обычно в UTF-8. len возвращает число байт, а не символов: кириллица занимает 2 байта, поэтому len("привет") == 12. Руна (rune = int32) — код символа Unicode. for range по строке идёт по рунам, индекс s[i] — по байтам.
- Число символов — utf8.RuneCountInString
- []rune(s) — срез рун для работы с символами по индексу
- Сборка строки в цикле — strings.Builder, конкатенация копирует
А ещё Преобразования string ↔ []byte копируют данные
Подробно
Устройство. Строка — пара {указатель, длина}, данные неизменяемы. Подстрока s[2:6] разделяет память с исходной.
Байты и руны. UTF-8 кодирует символы 1–4 байтами: латиница — 1 байт, кириллица — 2, эмодзи — 4. Поэтому индексация по байтам может попасть в середину символа.
Перебор:
for i := 0; i < len(s); i++— байты;for i, r := range s— руны, i — байтовое смещение начала руны;[]rune(s)— если нужен доступ по номеру символа.
Эффективная сборка: strings.Builder или bytes.Buffer; strings.Join для склейки среза.
Пакеты: strings (поиск, замена, разбиение), strconv (числа ↔ строки), unicode/utf8.
Пример
s := "привет"
fmt.Println(len(s)) // 12
fmt.Println(utf8.RuneCountInString(s)) // 6
for i, r := range s {
fmt.Println(i, string(r)) // 0 п, 2 р, 4 и ...
}
fmt.Println(s[0]) // 208 — первый байт, не букваЧто хотят услышать
- Строка как байты в UTF-8.
- len в байтах, руны, range.
- strings.Builder для сборки.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗len("привет") == 6
- ✗s[i] возвращает i-й символ Unicode
- ✗Строки в Go изменяемы
- ✓Неизменяемые байты UTF-8; len — в байтах, range — по рунам
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.