Строки и UTF-8 в Go
Вопрос
Объясните, как в Go устроены строки, байты и руны. Как правильно работать с текстом на русском?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Строка это неизменяемая последовательность байтов, обычно UTF-8
`len` даёт байты, `utf8.RuneCountInString` символы
byte это uint8, rune это int32 кодовая точка
`range` по строке декодирует руны, индексы байтовые
Для посимвольных операций `[]rune`, для склейки `strings.Builder`
Конвертации `[]byte(s)` и `string(b)` обычно копируют
Что могут спросить следом
- Как обрезать строку до 10 символов, не сломав UTF-8?
- Почему длина эмодзи может быть больше одной руны?
Разбор
Строка в Go это неизменяемый набор байтов с длиной. Исходники Go в UTF-8, поэтому литералы тоже в UTF-8, но язык не запрещает класть туда любые байты. len(s) считает байты: у «привет» их 12. Отдельный символ это руна, то есть int32 с кодовой точкой Unicode, а byte это uint8. Индекс s[i] даёт байт, поэтому для кириллицы им пользоваться нельзя. range по строке декодирует UTF-8 и выдаёт байтовый индекс и руну. Для посимвольных операций, например обрезки до N символов или разворота, перевожу в []rune, или иду range и отсчитываю руны, чтобы резать по байтовому индексу без лишней аллокации. Для склейки использую strings.Builder. Помню, что []byte(s) копирует, и в горячем коде стараюсь работать с одним представлением. И что «символ» для человека иногда состоит из нескольких рун: эмодзи с цветом кожи или флаги.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Строки, байты и руны»
- Байты и символы в строке Go
- Разворот строки с кириллицей на Go
- Сжатие RLE для строк UTF-8 на Go
- Палиндром с кириллицей и знаками на Go
- Перенос текста по ширине в символах на Go
- Что выведет Go: len и range по строке с кириллицей
- Что выведет Go: руны, байты и преобразования
- Что выведет Go: сравнение и срезы строк