Can the implant be split into different modules?

I am trying to split impl

into different modules. Items in child blocks impl

must be accessible to the parent impl

, but not publicly accessible by users of the implemented structure / enumeration.

Here's my attempt:

mod foo {
    pub struct Foo {
        field: String
    }

    impl Foo {
        pub fn new() -> Foo {
            Foo { field: "Joe".to_string() }
        }
        pub fn pubfn(&self) {
            self.my_impl();
        }
    }

    // Ideally, this should be in a separate file
    mod foo_impl_details {
        impl super::Foo {
            // If I make this `pub`, it will be publicly visible to
            // users of `Foo`, not just the impl block in `super`
            fn my_impl(&self) {
                println!("{} reporting for duty!", self.field);
            }
        }
    }
}

fn main() {
    let foo = foo::Foo::new();
    foo.pubfn();
}

      

This results in a compilation error:

<anon>:11:13: 11:27 error: method `my_impl` is private
<anon>:11             self.my_impl();
                      ^~~~~~~~~~~~~~

      

If I mark the my_impl

method pub

, it will be public not only to the parent module impl

, but also to external users foo::Foo

, which I don't want.

+3


source to share


3 answers


This is similar to expected behavior: a method my_impl

is private and therefore only visible within the module in which it is declared. On the other hand, it is weird that the version pub

is visible all over the place, despite being foo_impl_details

a private module. I wrote # 16398 about this.

You can decouple modules (and therefore files, since it is the mod foo { ... }

same as mod foo;

code in foo.rs

or foo/mod.rs

) while maintaining privacy by using standalone functions like

mod foo {
    pub struct Foo {
        field: String
    }

    impl Foo {
        pub fn new() -> Foo {
            Foo { field: "Joe".to_string() }
        }
        pub fn pubfn(&self) {
            foo_impl_details::my_impl(self);
        }
    }

    mod foo_impl_details {
        fn my_impl(x: &super::Foo) {
            println!("{} reporting for duty!", x.field);
        }
    }
}

      

There is no difference between independent functions and methods other than the call syntax.



Also, there are a lot of problems with writing non-trait impls not contiguous with the type declaration, so this behavior is probably not by design, for example.

And thus an RFC to (temporarily) remove this feature.

+1


source


It works.



mod foo {
    use self::extension::Extension;

    pub struct Foo {
        field: String
    }

    impl Foo {
        pub fn new() -> Foo {
            Foo { field: "Joe".to_string() }
        }
        pub fn pubfn(&self) {
            self.my_impl();
        }
    }

    mod extension {
        pub trait Extension {
            fn my_impl(&self);
        }
        impl Extension for super::Foo {
            fn my_impl(&self) {
                println!("{} reporting for duty!", self.field);
            }
        }
    }
}

      

+1


source


Regular impl

blocks? Well, this is something that is currently quite awkward, and while you can work around these errors a little, it can be removed . I highly recommend not trying this in the first place.

As for the implementations of the trait, they can go anywhere in the box.

+1


source







All Articles