tezvyn:

Rust Item Visibility: Private by Default

AI-drafted, machine-checkedSource: doc.rust-lang.orgintermediate

In Rust, all items are private by default. Think of modules as locked rooms; you need the `pub` keyword to unlock the door. This is crucial for creating a public API or letting modules interact.

WHY IT EXISTS Rust's privacy rules exist to enforce strict encapsulation. By making everything private by default, Rust forces developers to be intentional about what constitutes a public API. This prevents other parts of the code (or other crates) from depending on internal implementation details, making it much safer to refactor and evolve a codebase over time.

THE MENTAL MODEL Think of a Rust module tree like a filesystem where every new directory is created with owner-only permissions. Even if you know the exact path to a file, you can't access it unless every single directory in that path is marked as publicly accessible. The pub keyword is how you grant that access, one level at a time.

HOW IT WORKS By default, all items in Rust (functions, structs, enums, modules, etc.) are private. They can only be accessed by code within the same module or in child modules. To make an item visible to its parent module and beyond, you must prefix its definition with the pub keyword. This visibility is hierarchical. For an item deep inside a module tree to be accessible from the outside, it and all of its parent modules in the path must be marked pub.

WHEN TO USE IT Use pub when you are defining the public Application Programming Interface (API) of your crate. These are the functions, structs, and enums that you intend for users of your library to rely on. You also use pub for internal organization, such as when a function in one module needs to call a helper function defined in a sibling module.

WHEN NOT TO USE IT Avoid using pub for internal implementation details. If a helper function or a data structure is only used within its own module, keep it private. This gives you the freedom to change, refactor, or even remove it later without breaking any code that depends on your crate's public API.

ONE CANONICAL EXAMPLE Imagine a module structure: mod front_of_house { mod hosting { fn add_to_waitlist() {} } }. If you try to call crate::front_of_house::hosting::add_to_waitlist() from your crate root, the compiler will fail with an error: module 'hosting' is private. Even though the path is correct, you can't "see" inside front_of_house to get to hosting. The fix requires making the entire path public: pub mod front_of_house { pub mod hosting { pub fn add_to_waitlist() {} } }.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.