Введение#
Писать безопасный и быстрый код — это здорово, но иногда полезно понимать, как именно наши данные располагаются на физическом уровне в оперативной памяти. В Rust компилятор берет на себя управление памятью, оптимизируя размеры типов и выравнивание. В этой статье мы разберем основные понятия Type Layout в Rust.
Поведение компилятора по умолчанию#
- Управление памятью: Компилятор Rust автоматически рассчитывает и задает типу такие размеры (
size) и выравнивание (alignment), которые гарантированно удовлетворяют техническим требованиям всех его внутренних полей на целевой архитектуре процессора. - Паддинг (Padding): Компилятор имеет право автоматически вставлять неявные байты заполнения (паддинг) в структуру для обеспечения корректного выравнивания данных в памяти.
- Переупорядочивание полей: По умолчанию Rust не гарантирует сохранение порядка полей, написанного в коде. Компилятор оставляет за собой право произвольно менять порядок полей в кортежах, структурах и перечислениях для оптимизации размера и минимизации паддинга.
Давайте изучим выравнивание, размеры типов, использование атрибутов представления #[repr(...)] и работу с тегами перечислений на интерактивных слайдах ниже:
Детали реализации и шаги:#
Шаг 1. Выравнивание и размер по умолчанию:
- Каждому типу данных требуется выравнивание в памяти: адрес начала данных должен быть кратен выравниванию типа (обычно степени двойки: 1, 2, 4, 8 байт).
- Из-за этого между полями могут образовываться пустые байты — паддинг.
- По умолчанию (представление
repr(Rust)) компилятор переупорядочивает поля структурыFooтак, чтобы они занимали 8 байт вместо 12 байт, размещая сначала самые строгие по выравниванию типы.
Шаг 2. Управление расположением данных с помощью атрибутов: Для явного изменения логики размещения данных в памяти и обеспечения совместимости с другими языками используются специальные атрибуты представления:
#[repr(C)]— отключает оптимизацию переупорядочивания полей Rust и выстраивает их строго в том порядке, в котором они объявлены (совместимо с ABI языка C).#[repr(align(N))]— принудительно устанавливает минимальное выравнивание типа в памяти (например, 16 байт).#[repr(transparent)]— гарантирует, что тип имеет точно такое же представление в памяти и ABI, как и его единственное некорректное поле (используется для newtype-оберток).
Шаг 3. Явное тегирование перечислений (Enum Discriminants):
- Для перечислений можно жестко фиксировать тип числового тега (дискриминанта) в памяти и присваивать явные числовые значения каждому варианту.
- Это позволяет осуществлять безопасное приведение типов (кастинг) из перечисления в целочисленный тип с помощью ключевого слова
as.
Проверь свои знания!#
Пройдите короткий интерактивный тест, чтобы закрепить понимание расположения типов данных в памяти.
История обновлений
- Добавил интерактивные слайды с запускаемым кодом примеров и тесты по низкоуровневому представлению типов в памяти.

