2016-12-26 3 views
2
mod root { 
    mod foo { 
     pub struct Foo { 
      i: i32, 
     } 
    } 
    mod bar { 
     pub struct Bar { 
      f: ::root::foo::Foo, 
     } 
     impl Bar { 
      pub fn new(i: i32) -> Self { 
       Bar { f: ::root::foo::Foo { i: i } } 
      } 
     } 
    } 
} 
fn main() {} 

playgroundДоступ частных полей из различных модулей

Пользователь должен иметь возможность взаимодействовать с Foo, но пользователь не должен иметь возможность построить его вручную, так как это небезопасно.

Модуль bar должен все еще иметь возможность создавать Foo. Насколько я знаю, единственный способ сделать это - поставить Foo внутри модуля root или внутри модуля bar.

Есть ли более чистый способ решить эту проблему? Я назвал модули здесь foo и bar, но в моем коде они представляют собой отдельные файлы, такие как foo.rsbar.rs. Можно ли положить foo.rsbar.rs в тот же модуль, чтобы они могли видеть частные поля, но все же жить в отдельных файлах?

Мое настоящее обходное решение состояло в том, чтобы разоблачить общественный небезопасный метод для Foo.

+2

Почему бы вам не написать функцию «Foo :: new», которая безопасно создает «Foo»? –

+0

Не могли бы вы настроить getter для частного var, к которому хотите получить доступ? Таким образом, вы можете защитить любой доступ. Вы также можете сделать что-то вроде конструктора Foo (так используя новый), запустите конструкцию таким образом, чтобы она была успешной, только если выполнено какое-либо условие, например, требуемый аргумент конструктора arg должен быть экземпляром квалификационного компонент и т. д. Вы не можете создать компонент, не поставляя конкретный экземпляр определенного типа, и если он уже сконструирован, не создавайте новый, не возвращайте существующий, а другой - такой. –

ответ

1

Я думаю, что я нашел лучший обходной путь

pub mod root { 
    use self::foo::create_foo; 
    mod foo { 
     pub struct Foo { 
      i: i32, 
     } 
     impl Foo{ 
      pub fn hello_foo(&self){ 
       println!("Hello foo"); 
      } 
     } 
     pub fn create_foo(i: i32) -> Foo{ 
      Foo { i: i } 
     } 
    } 
    pub mod bar { 
     pub struct Bar { 
      pub f: ::root::foo::Foo, 
     } 
     impl Bar { 
      pub fn new(i: i32) -> Self { 
       Bar { f: ::root::foo::create_foo(i) } 
      } 
     } 
    } 
} 
fn main() { 
    //still private 
    //let f = root::foo::create_foo(42); 
    let b = root::bar::Bar::new(42); 
    b.f.hello_foo(); 
} 

playground

Выставляю открытый конструктор create_foo в foo, но модуль foo до сих пор остается частной, и я только разоблачить create_foo в root означает, что bar может теперь создайте Foo, но create_foo по-прежнему закрыто за пределами root.

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