Структуры
Карточка книги содержит название, год и число экземпляров. Три отдельные стопки листков легко перепутать: год одной книги окажется рядом с остатком другой. Одна карточка собирает связанные сведения в единое значение. Структура делает то же для программы.
Мы не строим библиотечную систему. Возьмём маленькую карточку товара и добавим операцию, которая вычисляет общую стоимость.
Одна мысль урока
Структура объединяет разные поля в одно значение с понятным именем.
Опора из прошлого урока: errdefer и безопасный откат.
От картинки к записи
Структура
объявляется через struct. Внутри перечислены поля: price: u32, count: u16. Каждое поле имеет
роль и тип. После закрывающей фигурной скобки объявления стоит точка с запятой, потому что мы
завершаем привязку имени Item к значению типа.
Создание Item{ .price = 120, .count = 3 } подписывает поля по имени. Порядок аргументов не нужно вспоминать по внешнему документу. Доступ item.price читает цену конкретного значения, а не цену всех товаров программы. Если экземпляров два, их поля независимы.
Поля могут иметь значения по умолчанию. Например, count: u16 = 1 позволяет не указывать количество при создании. Значение по умолчанию должно быть настоящей договорённостью задачи, а не способом скрыть незаполненные данные. Если без цены карточка некорректна, лучше требовать её явно.
Внутри структуры можно объявлять функции. fn total(self: Item) u64 получает саму карточку обычным параметром. Вызов item.total() удобная форма записи: смысл остаётся «передать item в функцию». Здесь нет скрытого изменяемого глобального объекта. Чтобы изменить поля оригинала, метод мог бы принять self: *Item, но наш расчёт только читает.
Расширим цену до u64 до умножения, чтобы результат u32 * u16 поместился. Максимальная цена и максимальное количество вместе требуют больше 32 разрядов. Эта деталь не относится к форме структуры, но показывает, как составные типы соединяются с уже изученной арифметикой. Хорошее имя типа не спасёт неправильный диапазон результата.
Присваивание структуры копирует её значение. Если поля содержат числа, это понятная независимая карточка. Если поле содержит срез, копируется представление среза, а не байты, на которые он смотрит. Поэтому структура со строкой не всегда владеет строкой. Владение нужно описывать отдельно в договоре функции.
Обычная структура не предназначена для угадывания двоичной раскладки чужого файла. Компилятор может выбирать размещение полей по правилам языка. Для совместимости с C и точного представления существуют другие формы, к которым вернёмся позже. Сегодня задача структуры смысловая: держать связанные факты вместе и не путать их роли.
премиум-урок
Продолжение в премиуме: 1 200 ₽ в месяц или 10 000 ₽ в год. Вместе с ним серверные проверки задач и школьные токены AI-коуча.
Оплата пока не подключена: премиум и курсы открываются промокодом.