Объясните разницу между `byte` и `rune` в Go.

Ответ

В Go byte и rune используются для представления символьных данных, но они служат разным целям и имеют фундаментальные отличия.

Байт (byte)

  • Что это? byte — это псевдоним (алиас) для типа uint8.
  • Размер: 8 бит (1 байт).
  • Представление: Хранит целое число от 0 до 255.
  • Назначение: Используется для работы с сырыми двоичными данными или с символами в кодировке ASCII, где каждый символ занимает ровно один байт.

Руна (rune)

  • Что это? rune — это псевдоним (алиас) для типа int32.
  • Размер: 32 бита (4 байта).
  • Представление: Хранит кодовую точку Unicode (Unicode Code Point).
  • Назначение: Используется для представления любого символа Unicode. Это стандартный способ работы с символами в Go, особенно когда речь идет о многобайтовых символах (например, кириллица 'ы', китайские иероглифы '世', эмодзи '🚀').

Ключевое различие на практике

Строка в Go — это, по сути, неизменяемый срез байтов ([]byte) в кодировке UTF-8. Это означает, что len() вернет количество байтов, а не символов (рун).

Пример:

package main

import "fmt"

func main() {
    s := "Go-мир"

    // len() возвращает количество байтов
    fmt.Printf("Строка: %sn", s)
    fmt.Printf("Байтов: %dn", len(s)) // Вывод: 9 (G:1, o:1, -:1, м:2, и:2, р:2)

    // Для подсчета символов (рун) нужно преобразование
    runes := []rune(s)
    fmt.Printf("Рун (символов): %dn", len(runes)) // Вывод: 6
}

Итерация по строке

Разница также проявляется при итерации:

  • for i := 0; i < len(s); i++: итерируется по байтам.
  • for index, runeValue := range s: итерируется по рунам. Go автоматически декодирует UTF-8 последовательности.

Итог

Характеристикаbyterune
Псевдоним дляuint8int32
ПредставляетОдин байт данныхКодовую точку Unicode
ИспользованиеASCII, бинарные данныеЛюбые символы, текст
len("A")1-
len("ы")2-
len([]rune("ы"))-1