ProgrammingBackend Developer

Explain how the access modifier system (visibility modifiers) works in Rust at the level of using structures and their fields. What is the complexity of managing access to nested structures?

Pass interviews with Hintsage AI assistant

Answer.

Background

In Rust, visibility modifiers (pub, pub(crate), pub(super)) emerged as a mechanism for encapsulation and clear control over access to data and functions, which was lacking in C. The idea is to limit the visibility of module elements and provide library users only what is really necessary.

Problem

The key complexity is that even if the structure itself is declared public (pub), its fields remain private by default. There is also often the question of how to properly organize access to nested structures and modules without violating encapsulation and making the API "leaky" or, on the other hand, too closed.

Solution

For structures, it is necessary to specify access modifiers for fields separately. When designing auto-generated structures or stored types, it is important to carefully consider which parts should be exposed and which should remain hidden. This is a crucial part of API and code architecture.

Code example:

mod outer { pub struct Exposed { pub field: i32, hidden: bool, } } // Access to the "field" is available, // hidden — is not. let e = outer::Exposed { field: 42, hidden: true }; println!("{}", e.field); // e.hidden // compilation error

Key features:

  • All structure fields are private by default, even if the structure itself is public.
  • Access to fields must be explicitly allowed through pub or pub(...).
  • pub(crate) and pub(super) provide finer control over the level of access to module internals.

Trick questions.

Can a structure declared as pub be completely inaccessible outside the current module?

Yes, if all fields of the structure remain private, it is public only by name — it cannot be created or initialized outside the module.

Can a private field of a structure become accessible through inheritance or another means, bypassing the modifier system?

No, Rust does not have classical inheritance like OOP languages. Access to private fields is controlled by the module and is significantly limited.

What happens if you create a structure with public fields but declare the module private?

The structure and its fields will not be visible outside the parent module — modifiers do not extend beyond the visibility scope of the parent module.

Common mistakes and anti-patterns

  • Making a structure public but without public fields/methods — a useless abstraction.
  • Providing excessive pub, exposing the internals of the API and complicating support.
  • Wrongly assuming that pub automatically makes fields accessible.

Real-life example

**Negative case

The user declared a structure as pub, but all fields remained private. As a result, external code cannot use it correctly, cannot create an instance or retrieve values.

Pros:

  • Unintentional limitation of visibility protects internal data.

Cons:

  • Cannot use the structure outside the module, even if intended.

**Positive case

The user opened only necessary fields via pub, leaving sensitive details private. Access is done through getters/setters.

Pros:

  • Guarantees encapsulation and interface stability.

Cons:

  • Requires more boilerplate code (getters/setters)