Руны в Golang
В Go руны (rune
) — это тип данных, представляющий символ Unicode. По сути, rune
— это псевдоним для типа int32
, который используется специально для работы с символами Unicode. Давайте разберемся подробнее, что это такое и как с этим работать.
Что такое rune
в Go?
rune
представляет собой кодовую точку Unicode (code point).- Кодовая точка — это числовое представление символа в стандарте Unicode. Например:
A
→ кодовая точка 65 (U+0041)你
→ кодовая точка 20320 (U+4F60)😊
→ кодовая точка 128522 (U+1F60A)
- Тип
rune
используется для удобной работы с символами, так как строки (string
) в Go хранятся как последовательности байт (в кодировке UTF-8), и напрямую работать с символами бывает сложнее.
Почему нужен rune
, если есть byte
?
byte
— это псевдоним дляuint8
и представляет собой один байт. Но символ Unicode может занимать больше одного байта в UTF-8.rune
(илиint32
) позволяет работать с символами, которые занимают до 4 байт, так как это максимальная длина кодовой точки Unicode.
Пример:
1 2 3 4 |
s := "你好" // Два символа Unicode fmt.Println(len(s)) // 6 (каждый символ занимает 3 байта в UTF-8) fmt.Println([]rune(s)) // [20320 22909] (кодовые точки символов) |
Как работает rune
- Инициализация: Руну можно инициализировать через символ или числовую кодовую точку:
1234var r rune = 'A' // Символ 'A'fmt.Println(r) // 65 (кодовая точка)fmt.Printf("%c\n", r) // 'A' (символ)
- Приведение строки к рунам: Используйте
[]rune
, чтобы преобразовать строку в срез рун:12345s := "Hello, 世界"runes := []rune(s)fmt.Println(runes) // [72 101 108 108 111 44 32 19990 30028]fmt.Printf("%c\n", runes) // [H e l l o , 世 界] - Итерация по символам строки: Итерация по строке через
range
автоматически обрабатывает руны:12345s := "你好, 世界"for i, r := range s {fmt.Printf("Index: %d, Rune: %c, Code Point: %U\n", i, r, r)}Вывод:
1234567Index: 0, Rune: 你, Code Point: U+4F60Index: 3, Rune: 好, Code Point: U+597DIndex: 6, Rune: ,, Code Point: U+002CIndex: 8, Rune: , Code Point: U+0020Index: 9, Rune: 世, Code Point: U+4E16Index: 12, Rune: 界, Code Point: U+754C - Работа с отдельными символами: Вы можете преобразовывать руны в строки и обратно:
1234r := '世'fmt.Println(string(r)) // "世"fmt.Println(r) // 19990 (кодовая точка)
Полезные операции с рунами
- Длина строки в символах (рунах):
1234s := "你好, 世界"fmt.Println(len(s)) // Длина в байтах (13)fmt.Println(len([]rune(s))) // Длина в символах (6)
- Проверка типа символа: Используйте пакет
unicode
для работы с символами:1234567import "unicode"r := 'A'fmt.Println(unicode.IsLetter(r)) // true (является буквой)fmt.Println(unicode.IsDigit(r)) // false (не цифра)fmt.Println(unicode.IsSpace(r)) // false (не пробел) - Фильтрация строк: Удалим все символы, кроме букв:
1234567891011121314import "unicode"func filterLetters(s string) string {var result []runefor _, r := range s {if unicode.IsLetter(r) {result = append(result, r)}}return string(result)}fmt.Println(filterLetters("Hello, 世界! 123")) // "Hello世界"
- Сравнение рун:
12345r1 := 'a'r2 := 'A'fmt.Println(r1 == r2) // falsefmt.Println(unicode.ToLower(r2) == r1) // true (приводим к нижнему регистру)
Пакет unicode
Пакет unicode
предоставляет множество функций для работы с рунами:
- Проверки типов символов:
unicode.IsLetter(rune)
— проверяет, является ли символ буквой.unicode.IsDigit(rune)
— проверяет, является ли символ цифрой.unicode.IsSpace(rune)
— проверяет, является ли символ пробелом.
- Регистры:
unicode.ToLower(rune)
— преобразует в нижний регистр.unicode.ToUpper(rune)
— преобразует в верхний регистр.unicode.ToTitle(rune)
— преобразует в заглавный регистр.
Кодировка и руны
Go использует UTF-8 для строк, и rune
— это удобный способ работы с Unicode. Преобразование между UTF-8 и рунами происходит автоматически:
- Строка → байты:
123s := "你好"fmt.Println([]byte(s)) // [228 189 160 229 165 189] - Байты → руны:
123s := "你好"fmt.Println([]rune(s)) // [20320 22909]
Пример: поиск уникальных символов
Вот пример программы для подсчета уникальных символов в строке:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package main import "fmt" func uniqueRunes(s string) map[rune]int { counts := make(map[rune]int) for _, r := range s { counts[r]++ } return counts } func main() { s := "你好, 世界! Hello!" counts := uniqueRunes(s) for r, c := range counts { fmt.Printf("Rune: %c, Count: %d\n", r, c) } } |
Заключение
rune
— это мощный инструмент для работы с символами Unicode в Go.- Он удобен, когда нужно работать с многоязычным текстом, анализировать строки или манипулировать символами.
- Используйте
rune
в сочетании сunicode
для проверки типов символов, изменения регистра или других операций.
Recommended Posts
Что такое oneof в Protobuf?
25.04.2024