2016-01-04 5 views
1

Я работаю над реализацией шаблона репозитория в Rust.Более одного файла в модуле

мне нужно иметь две (или более) файлов:

  • entity.rs - описания данных
  • repository.rs - методы
  • доступа к данным ...

Проблема:

Один файл подразумевает один мод. Это означает, что для функции в repository.rs для доступа к полю структуры от entity.rs требуется, чтобы field был pub. Есть ли способ избежать этого?

+1

Почему возникает проблема 'pub' для вас? (дополнительное чтение: https://doc.rust-lang.org/reference.html#visibility-and-privacy) –

+0

Некоторые поля должны быть недоступны напрямую, например, геттер или сеттер в качестве примера – Gedweb

+0

Итак, если я понимаю, поле должно быть 'pub' внутренне (в пределах 2/3 модулей), но частным для внешних клиентов ящика (или, возможно, других модулей в ящике)? –

ответ

5

В ржавчине модули являются автономными. В отличие от 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. Контроль над тем, кто видит, что будет достигнуто путем тщательного экспорта.

Это решение, вероятно, приведет вас в безумное состояние.

+1

Желаю, чтобы у меня был дополнительный +1 только для последнего замечания ... –

+0

Второе решение более гибкое, подумайте, что мне нужно. Благодаря! знак равно – Gedweb

Смежные вопросы