2017-07-25 5 views
2

Gibt es einen besseren Weg, als alles in das gleiche Modul zu stecken?Ist es möglich, ein Modul zu haben, das teilweise außerhalb einer Kiste und teilweise nur innerhalb der Kiste zugänglich ist?

sub_module.rs

pub struct GiantStruct { /* */ } 

impl GiantStruct { 

    // this method needs to be called from outside of the crate. 
    pub fn do_stuff(/* */) { /* */ }; 
} 

lib.rs

pub mod sub_module; 
use sub_module::GiantStruct; 

pub struct GiantStructBuilder{ /* */ } 

impl GiantStructBuilder{ 
    pub fn new_giant_struct(&mut self) -> GiantStruct { 
     // Do stuff depending on the fields of the current 
     // GiantStructBuilder 
    } 
} 

Das Problem mit GiantStructBuilder::new_giant_struct() ist; Diese Methode sollte eine neue GiantStruct erstellen, aber entweder pub fn new() -> GiantStruct innerhalb von sub_module.rs oder alle Felder von GiantStruct müssen öffentlich sein. Beide Optionen ermöglichen den Zugriff von außerhalb meiner Kiste.

Während diese Frage zu schreiben, wurde mir klar, dass ich etwas tun könnte:

sub_module.rs

pub struct GiantStruct { /* */ } 

impl GiantStruct { 
    // now you can't call this method without an appropriate 
    // GiantStructBuilder 
    pub fn new(&mut GiantStructBuilder) -> GiantStruct { /* */ }; 

    pub fn do_stuff(/* */) { /* */ }; 
} 

Dies ist jedoch wirklich eingängig scheint, als normalerweise der Anrufer die Sache ist, das ist handeln, während die Funktionsvariablen sind, worauf man einwirkt, was natürlich nicht der Fall ist, wenn man so vorgeht. So würde ich immer noch gerne wissen, ob es einen besseren Weg gibt ...

Antwort

2

Sie könnten die neu stabilisierte pub(restricted) privacy verwenden.

Dadurch können Sie Typen/Funktionen nur einem begrenzten Modulbaum, z.

pub struct GiantStruct { /* */ } 

impl GiantStruct { 
    // Only visible to functions in the same crate 
    pub(crate) fn new() -> GiantStruct { /* */ }; 

    // this method needs to be called from outside of the crate. 
    pub fn do_stuff(/* */) { /* */ }; 
} 

Oder Sie könnten diese auf Ihrem GiantStruct auf Felder anwenden, damit Sie es von GiantStructBuilder zu erstellen:

pub struct GiantStruct { 
    pub(crate) my_field: u32, 
} 

Statt crate Sie auch super nutzen könnten angeben sie auf das übergeordnete Modul nur öffentlich ist .

Verwandte Themen