Ответ
rune в Go — это псевдоним (алиас) для типа int32.
Он используется для представления Unicode Code Point (кодовой точки Юникода). В отличие от byte, который представляет один байт, rune может представлять любой символ, даже если для его кодирования в UTF-8 требуется несколько байт.
Ключевые отличия от byte:
- Размер:
byte(uint8) всегда 1 байт.rune(int32) — 4 байта. - Назначение:
byteдля работы с бинарными данными,rune— для работы с текстовыми символами. - Итерация по строке:
- Стандартный
forцикл по строке итерируется по байтам. - Цикл
for ... rangeпо строке итерируется по рунам (символам).
- Стандартный
Пример, демонстрирующий разницу:
str := "Привет"
// 1. Итерация по байтам. Символы кириллицы в UTF-8 занимают 2 байта.
fmt.Printf("Длина в байтах: %dn", len(str)) // Вывод: Длина в байтах: 12
// 2. Итерация по рунам (символам).
runes := []rune(str)
fmt.Printf("Длина в рунах (символах): %dn", len(runes)) // Вывод: Длина в рунах (символах): 6
// Цикл for...range декодирует руны на лету
for i, r := range str {
fmt.Printf("Индекс байта: %d, Символ: %cn", i, r)
}
// Вывод покажет, что индекс (i) скачет не на 1, а на 2 (размер символа в байтах)
Использование rune необходимо для корректной обработки многоязычного текста.
Ответ 18+ 🔞
Так, слушай, про rune в Go. Это ж, блядь, не просто так, это пиздец как важно, если с текстом работаешь.
Вот смотри, rune — это просто псевдоним для int32, типа. Но не думай, что это просто число. Это, сука, Unicode Code Point, кодовая точка, ёпта. По-простому — один целый символ, какой угодно. В отличие от этого убожества byte, который один байт — и нахер сдох, если символ больше байта.
Чем они, блядь, отличаются, эти два пидораса:
- Размер:
byte(uint8) — это один байт, коротышка. Аrune(int32) — четыре байта, здоровый мужик, может вместить любого, даже самого ебучого иероглифа. - Для чего:
byte— для бинарного дерьма, данных.rune— для нормальных человеческих букв и смайликов. - Итерация по строке — вот где пиздец:
- Обычный
forцикл по строке бежит по байтам. Полный отстой, если у тебя не ASCII. - А вот
for ... rangeпо строке — тот уже умный, он итерируется по рунам, то есть по нормальным символам.
- Обычный
Смотри пример, а то нихуя не понятно:
str := "Привет"
// 1. Считаем байты. Кириллица в UTF-8 — по 2 байта на букву.
fmt.Printf("Длина в байтах: %dn", len(str)) // Вывод: Длина в байтах: 12 (6 букв * 2 байта)
// 2. Считаем руны (символы). Вот это уже по-человечески.
runes := []rune(str)
fmt.Printf("Длина в рунах (символах): %dn", len(runes)) // Вывод: Длина в рунах (символах): 6
// Цикл for...range — он молодец, сам всё декодирует.
for i, r := range str {
fmt.Printf("Индекс байта: %d, Символ: %cn", i, r)
}
// Смотри на индекс (i) — он будет прыгать не на 1, а на 2, потому что каждый символ — два байта. Вот и вся магия, блядь.
Короче, если хочешь работать с текстом и не обосраться — используй rune. Иначе потом будешь сидеть и думать, почему у тебя строка из трёх иероглифов длиной в 12 байт, и нихуя не сходится.