В ржавчине модули являются автономными. В отличие от C++ или Java нет обмана с помощью friend
или использования отражения.
Таким образом, если вы (произвольно) попытаетесь отделить определение struct
от методов, отвечающих за поддержание его инкапсуляции, вы будете бороться против языка.
Решение 1: Предпочитают не являющегося членом без друга функции
Определить методы абсолютно требующие доступа к полям в entity.rs
; если вы следуете директиве «Предпочесть не-членские функции, отличные от друга» от C++, вы должны увидеть, что на самом деле большинство методов НЕ нужно напрямую обращаться к полям. Например, empty
может быть определен в терминах len
:
fn empty(c: &Container) -> bool { c.len() == 0 }
Затем repository.rs
можно добавить много других методов, если это необходимо, но должно пройти через «минимальный» интерфейс экспортируемого entity.rs
для достижения своих потребностей. Поскольку вы контролируете оба модуля, вы можете настроить методы entity.rs
по желанию, так что это не должно быть проблемой.
Я хотел бы отметить, что инкапсуляция-накрест, это разумного решения: сокращение числа методов, которые могут получить доступ к внутренности объекта уменьшает количество методов, которые могут поставить этот объект в нерабочем состоянии.
Это решение выгодно, потому что вы не боретесь с языком.
Решение 2: Total сплит
Другим решением является дублировать объекты:
- имеют внутреннюю сущность, полностью общественное
- имеют внешнюю сущность, непрозрачный
Это achie вед по:
pub struct SomeEntImpl {
pub field0: i32,
}
pub struct SomeEnt {
inner: SomeEntImpl,
}
Уставные модули будут даны ссылки на SomeEntImpl
, в то время как другие будут использовать ограниченный интерфейс, доступные через SomeEnt
. Контроль над тем, кто видит, что будет достигнуто путем тщательного экспорта.
Это решение, вероятно, приведет вас в безумное состояние.
Почему возникает проблема 'pub' для вас? (дополнительное чтение: https://doc.rust-lang.org/reference.html#visibility-and-privacy) –
Некоторые поля должны быть недоступны напрямую, например, геттер или сеттер в качестве примера – Gedweb
Итак, если я понимаю, поле должно быть 'pub' внутренне (в пределах 2/3 модулей), но частным для внешних клиентов ящика (или, возможно, других модулей в ящике)? –