← Назад к вопросам

Что такое тип rune?

1.0 Junior🔥 21 комментариев
#Другое

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Тип rune в Go

rune в языке Go — это псевдоним (alias) для типа int32, предназначенный для представления единичной кодовой точки (code point) Unicode. Это фундаментальный тип данных для корректной обработки текста, содержащего символы за пределами ASCII (кириллица, иероглифы, эмодзи и т.д.).

Основные характеристики

  1. Размер и представление

    type rune = int32 // определение встроенного типа
    

    Каждая переменная типа rune занимает ровно 4 байта (32 бита) и хранит числовое значение кодовой точки Unicode.

  2. Связь со string и byte Строки в Go по своей сути — это неизменяемые последовательности байт ([]byte). Однако при итерации по строке с помощью for range происходит автоматическое декодирование UTF-8:

    str := "Привет, 世界! 🚀"
    for index, r := range str {
        fmt.Printf("Позиция %d: руна %U = %c\n", index, r, r)
    }
    

    В этом примере r имеет тип rune, а не byte. Важно: индекс index показывает позицию в байтах, а не в символах, так как один символ UTF-8 может кодироваться 1-4 байтами.

Практическое применение и отличия

  • Преобразование строки в срез рун:

    s := "Йожык"
    runes := []rune(s) // []rune{'Й', 'о', 'ж', 'ы', 'к'}
    bytes := []byte(s)  // Байтовое представление UTF-8
    

    Операция []rune(s) явно декодирует строку в последовательность кодовых точек Unicode. Длина len(runes) будет равна 5 (количество символов), в то время как len(s) и len(bytes) вернут 10 (количество байт в UTF-8).

  • Сравнение с byte для не-ASCII текста:

    s := "Эмодзи 👍"
    fmt.Println(len(s))                    // 13 байт
    fmt.Println(len([]rune(s)))            // 8 символов (рун)
    fmt.Println(string(s[0]))              // Может вывести "" — обрезанный байт!
    fmt.Println(string([]rune(s)[0]))      // Корректно: "Э"
    

    Прямая индексация строки (s[0]) возвращает byte и опасна для многобайтовых символов.

Ключевые методы работы с рунами

В стандартной библиотеке Go пакет unicode предоставляет утилиты для анализа rune:

import "unicode"

r := 'A'
fmt.Println(unicode.IsLetter(r))  // true
fmt.Println(unicode.IsUpper(r))   // true
fmt.Println(unicode.ToLower(r))   // 'a'

cyrillicRune := 'Ж'
fmt.Println(unicode.Is(unicode.Cyrillic, cyrillicRune)) // true

Важные нюансы

  • Литералы рун записываются в одинарных кавычках: 'я', '🎮'. Значением является кодовая точка.
  • Не все руны — это "видимые символы". Существуют служебные, непечатаемые и комбинирующиеся кодовые точки (например, диакритические знаки).
  • Производительность: Использование []rune(s) создает новый аллоцированный слайс. Для большинства операций (поиск, подсчет символов) эффективнее итерация for range без материализации слайса рун.

Резюме

Тип rune — это абстракция Go для безопасной работы с Unicode. Он позволяет обрабатывать текст на естественном уровне символов, а не байтов, что критически важно для интернационализированных приложений. Понимание различий между string, []byte и []rune — обязательный навык для разработчика Go, работающего с текстовыми данными.