Adding private visibility to struct-fields **within** module

Currently I don't see any way to add private visibility to struct-fields within a module. Is there any effort for adding this functionality in future rust-releases?

Use-Cases:

  • enforce access-rules for developers working on the same module

Why?
Of course, things work without this functionality. But shouldn't a compiler facilitate the coding-process? I think it would be very nice to be able to write things like private some_field, which is only accessible for methods associated with the struct (similar to the private-keyword in java) and not from the outside (except through getter-functions).

How do you guys go about enforcing "private-access-rules" on certain struct-fields in rust?

If I'm feeling paranoid, I can just put the type inside a module of its own, and re-export it in the parent module. Heck, since you can define modules inline, you don't even need a separate file.

6 Likes

To ilustrate this point

mod private {
    pub struct MyStruct {
        field1: usize,
    }

    impl MyStruct {
        pub fn new(x: usize) -> Self {
            Self { field1: x }
        }
    }
}
use private::MyStruct;

// now other code in the module is forced to use the api definded by MyStruct

pub fn some_fn() {
    let _m = MyStruct::new(3); // works
    let _m = MyStruct { field1: 3 }; // doesn't work
}

Playground

2 Likes

I'd like to point out that from Rust's POV, the unit of functionality is the module, not types or functions. The latter are more seen as tools that can be used within the module to provide whatever needs to be provided.

From that POV, it makes little sense to make fields private w.r.t. the module they're defined in.

6 Likes

Module in Rust exist precisely to group related code in one place. If you want to argue that it's important enough usecase then you would need something less vague than shouldn't a compiler facilitate the coding-process? — as the bare minimum you should explain just how this feature “facilitates the development process”.

IMNSHO it would just confuse everyone.

In C++ or Java namespaces and packages are poor boundaries for private/public restrictions because anyone may expand them and thus break the encapsulation. It's trivial in C++ and not-so-trivial and that's why Java package-level visibility makes some sense. But adding new methods to the class, in both languages, is not possible except by changing definition of class. Which makes classes natural boundary for private/public definitions.

In Rust it's the opposite: anyone may add new methods for your struct and this makes “set of methods defined for a given type” pretty much useless for the invariants enforcement.

But not anyone may add a new module which makes modules perfect boundary for public/private separation.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.