В языке программирования Rust уровень доступа (видимости) к методам и полям структур регулируется модификаторами: pub, pub(crate), pub(super), а также отсутствием модификатора (по умолчанию — приватно).
Rust изначально спроектирован для обеспечения надёжности и изоляции компонентов. Контроль доступа к внутренним частям структур позволяет инкапсулировать данные и скрывать детали реализации, сохраняя только нужные интерфейсы публичными.
Разработчики часто сталкиваются с ситуациями, когда структура публична, но её поля остаются приватными, либо публичность поля оказывается недостаточной из-за ограничений видимости самой структуры или модуля. Особенно сложно понимать вложенные уровни: публичная вложенная структура может быть недоступна, если содержащий модуль скрыт, и наоборот.
В Rust модификаторы доступа применяются к структурам, их полям и методам, а также к модулям и функциям. Существуют следующие уровни:
pub — делает элемент доступным из любого места.pub(crate) — доступен только внутри текущего крейта.pub(super) — доступен только из родительского модуля.Пример кода:
mod outer { pub struct PublicStruct { pub field: u32, hidden: u32, } pub(crate) struct CrateStruct { pub value: i32, } struct PrivateStruct { pub secret: i32, } pub mod inner { pub(super) struct SuperStruct { pub super_field: u8, } } }
Ключевые особенности:
Если структура объявлена как pub, а её поля — без модификатора, можно ли к ним обратиться из другого модуля?
Нет, только сама структура становится публичной, но её поля остаются приватными внутри модуля. Для доступа к полю оно также должно быть объявлено с pub.
Что произойдёт, если объявить структуру как pub(crate), а поле внутри неё — pub?
Видимость ограничивается самой структурой. Даже если поле pub, получить к нему доступ за пределами крейта невозможно, так как структура недоступна.
pub(crate) struct Secret { pub data: i32, // pub не "проходит сквозь" pub(crate) }
Можно ли объявить структуру pub внутри приватного модуля и получить к ней доступ извне?
Нет. Итоговая видимость определяется минимумом между структурой и модулем. Если модуль приватен, структуры и функции внутри него также не видны вне этого модуля.
В проекте вся структура сделана публичной с открытыми полями для ускорения разработки. Позже стало сложно поддерживать обратную совместимость и контролировать доступ к полям, так как их изменяли напрямую.
Плюсы:
Минусы:
Для публичной структуры реализованы приватные поля и публичные методы-конструкторы/аксессоры. Структура экстпортируется только на нужном уровне модуля.
Плюсы:
Минусы: