Преобразование строк: []rune и []byte
1. Преобразование в []rune
Синтаксис
text := "Привет"
runes := []rune(text)
Результат: Срез рун, где каждый элемент — один Unicode-символ.
Полный пример
text := "Привет"
runes := []rune(text)
fmt.Printf("text: %s\n", text)
fmt.Printf("len(text) = %d байт\n", len(text))
fmt.Printf("[]rune(text): %v\n", runes)
fmt.Printf("len(runes) = %d символов\n", len(runes))
Вывод:
text: Привет
len(text) = 12 байт
[]rune(text): [1055 1088 1080 1074 1077 1090]
len(runes) = 6 символов
Объяснение:
"Привет"= 12 байт (6 символов × 2 байта)[]rune= 6 элементов (каждый — код символа)
2. Доступ к символам через []rune
text := "Привет"
runes := []rune(text)
for i, r := range runes {
fmt.Printf("[%d] = %c (код: %d)\n", i, r, r)
}
Вывод:
[0] = П (код: 1055)
[1] = р (код: 1088)
[2] = и (код: 1080)
[3] = в (код: 1074)
[4] = е (код: 1077)
[5] = т (код: 1090)
Теперь можно работать как с обычным срезом.
3. Изменение символов через []rune
text := "Привет"
runes := []rune(text)
// Меняем первый символ
runes[0] = 'Ч'
// Конвертируем обратно в строку
newText := string(runes)
fmt.Println(text) // "Привет" — оригинал не изменён
fmt.Println(newText) // "Чривет"
Механизм: Строки иммутабельны, изменяем через срез рун.
4. Преобразование в []byte
Синтаксис
simple := "Go"
bytes := []byte(simple)
Результат: Срез байтов (UTF-8 представление).
Пример с ASCII
simple := "Go"
bytes := []byte(simple)
fmt.Printf("simple: %s\n", simple)
fmt.Printf("[]byte: %v\n", bytes)
Вывод:
simple: Go
[]byte: [71 111]
ASCII символы: 1 символ = 1 байт.
Пример с кириллицей
text := "Привет"
bytes := []byte(text)
fmt.Printf("text: %s\n", text)
fmt.Printf("[]byte: %v\n", bytes)
fmt.Printf("Длина: %d байт\n", len(bytes))
Вывод:
text: Привет
[]byte: [208 159 209 128 208 184 208 178 208 181 209 130]
Длина: 12 байт
Кириллица: 1 символ = 2 байта в UTF-8.
5. Обратное преобразование
Из []byte в string
bytes := []byte{71, 111}
text := string(bytes)
fmt.Println(text) // "Go"
Из []rune в string
runes := []rune{1055, 1088, 1080, 1074, 1077, 1090}
text := string(runes)
fmt.Println(text) // "Привет"
Обратная конвертация всегда через string().
6. Сравнение []rune vs []byte
| Критерий | []rune |
[]byte |
|---|---|---|
| Элемент | Unicode символ (code point) | Байт (UTF-8) |
| Тип элемента | rune (int32) |
byte (uint8) |
| Размер элемента | 4 байта | 1 байт |
| Длина для “Привет” | 6 | 12 |
| Применение | Работа с символами | Работа с байтами (сеть, файлы) |
7. Когда использовать что
[]rune — работа с символами
text := "Привет, мир!"
runes := []rune(text)
// Получить первый символ
firstChar := runes[0] // 'П'
// Заменить символ
runes[7] = '❤'
result := string(runes) // "Привет,❤мир!"
// Подсчёт символов
count := len(runes) // 12
Используйте для: Манипуляции с текстом, подсчёт символов.
[]byte — работа с данными
text := "Hello"
bytes := []byte(text)
// Передача по сети
conn.Write(bytes)
// Запись в файл
file.Write(bytes)
// XOR шифрование
bytes[0] ^= 0xFF
// Обратно в строку
encrypted := string(bytes)
Используйте для: I/O операции, криптография, низкоуровневая работа.
8. Практические примеры
Подсчёт гласных
text := "Привет"
runes := []rune(text)
vowels := "аеёиоуыэюяАЕЁИОУЫЭЮЯ"
count := 0
for _, r := range runes {
if strings.ContainsRune(vowels, r) {
count++
}
}
fmt.Printf("Гласных: %d\n", count) // 2 (и, е)
Реверс строки
text := "Привет"
runes := []rune(text)
// Разворот среза рун
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
reversed := string(runes)
fmt.Println(reversed) // "тевирП"
Замена символа
text := "Hello, World!"
runes := []rune(text)
// Заменить все 'o' на '0'
for i, r := range runes {
if r == 'o' {
runes[i] = '0'
}
}
result := string(runes)
fmt.Println(result) // "Hell0, W0rld!"
9. Производительность
Копирование данных
text := "Привет"
// Преобразование КОПИРУЕТ данные
runes := []rune(text) // Выделяет новую память
bytes := []byte(text) // Выделяет новую память
Важно: Преобразования не бесплатны — создаётся новый срез.
Оптимизация
// ❌ Плохо: много преобразований
for i := 0; i < 1000; i++ {
runes := []rune(text)
// работа с runes
}
// ✅ Хорошо: одно преобразование
runes := []rune(text)
for i := 0; i < 1000; i++ {
// работа с runes
}
10. Итоги
✅ []rune(s) — преобразование в срез Unicode-символов
✅ []byte(s) — преобразование в срез байтов (UTF-8)
✅ string([]rune) — обратное преобразование из рун
✅ string([]byte) — обратное преобразование из байтов
✅ []rune позволяет корректно работать с символами
✅ []byte нужен для I/O операций и байтовой обработки
✅ Преобразования копируют данные — не бесплатны
✅ После преобразования можно изменять элементы как в обычном срезе
Ключевые паттерны:
// Работа с символами
runes := []rune(text)
runes[i] = 'X'
result := string(runes)
// Работа с байтами
bytes := []byte(text)
bytes[i] = 0xFF
result := string(bytes)
// Итерация (без преобразования)
for _, r := range text { // r — rune
fmt.Printf("%c", r)
}
Практическое правило:
Нужны символы (текст) → []rune
Нужны байты (данные) → []byte
Только чтение → for range (без преобразования)