Что такое руна (rune) в Go и чем она отличается от байта (byte)?

Ответ

В Go rune — это псевдоним (alias) для типа int32. Он используется для представления кодовой точки Unicode (Unicode code point).

Чтобы понять разницу, нужно знать, как Go работает со строками:

  • string: Это неизменяемая последовательность байтов, обычно в кодировке UTF-8.
  • byte: Это псевдоним для uint8, представляет один байт.
  • rune: Это псевдоним для int32, представляет один символ Unicode, который может занимать от 1 до 4 байт в UTF-8.

Ключевое отличие:

  • При итерации по строке с помощью стандартного for цикла вы получаете байты. Это некорректно для многобайтовых символов (кириллица, эмодзи).
  • При итерации по строке с помощью for ... range Go автоматически декодирует UTF-8 последовательности и возвращает руны.

Пример:

package main

import "fmt"

func main() {
    s := "Привет 👋"

    // 1. Итерация по байтам (неправильно для символов)
    fmt.Printf("Длина в байтах: %dn", len(s)) // len() возвращает кол-во байт
    // Вывод: Длина в байтах: 17

    // 2. Итерация по рунам (правильно для символов)
    runes := []rune(s)
    fmt.Printf("Длина в рунах (символах): %dn", len(runes))
    // Вывод: Длина в рунах (символах): 8

    // Использование for...range для получения рун
    for index, r := range s {
        fmt.Printf("Индекс байта: %d, Символ: %c, Код Unicode: %dn", index, r, r)
    }
}

Итог:

ТипПредставляетРазмерКогда использовать
byteОдин байт8 битДля работы с бинарными данными или ASCII-строками.
runeОдну кодовую точку Unicode32 битаДля корректной работы с текстом, который может содержать любые символы.