Строки
Работа с текстовыми данными, кодировка UTF-8, руны и операции над строками в Go.
Что изучим
- Внутреннее устройство строк: указатель и длина
- Кодировка UTF-8 и многобайтовые символы
- Тип rune для представления Unicode символов
- Доступ к элементам через байты и руны
- Итерация по строкам через for range
- Неизменяемость строк (immutability)
- Операции конкатенации и сравнения
Основные концепции
Внутренняя структура: строка в Go — это структура из двух полей: указатель Data на массив байтов и длина Len. При копировании строки копируется только структура (16 байт на 64-битной системе), сами данные остаются общими. Компилятор оптимизирует одинаковые литералы, размещая их в одном месте памяти.
Кодировка UTF-8: строки хранятся в UTF-8, где ASCII символы занимают 1 байт, кириллица 2-3 байта, эмодзи до 4 байтов. Функция len() возвращает количество байтов, а не символов. Для подсчёта символов используйте []rune или utf8.RuneCountInString.
Тип rune: алиас для int32, представляет Unicode code point (один символ). Объявляется одинарными кавычками: ‘А’. Двойные кавычки создают string. Для работы с Unicode символами преобразуйте строку в []rune.
Доступ к элементам: оператор s[i] возвращает byte (первый байт), что корректно для ASCII, но не для Unicode. Для многобайтовых символов используйте []rune(s)[i]. Прямое обращение к кириллице/эмодзи через s[i] даёт мусор — только первый байт из последовательности.
Итерация: цикл for i := 0; i < len(s); i++ проходит по байтам и некорректен для Unicode. Используйте for range, который автоматически итерирует по рунам, декодируя многобайтовые последовательности. Это идиоматичный способ для любых строк.
Неизменяемость: строки иммутабельны — нельзя изменить s[i]. Массив байтов находится в read-only памяти. Для модификации преобразуйте в []byte, измените и создайте новую строку через string(). Оригинальная строка не изменится.
Практические рекомендации: для ASCII допустимо использовать s[i], для Unicode только []rune(s)[i]. Всегда используйте for range для итерации. Помните, что len() возвращает байты, не символы.