Строки

Работа с текстовыми данными, кодировка 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() возвращает байты, не символы.