Structs

Visibility of Fields and Methods

In Rust, every item, struct field, and method is private by default. Marking a struct as pub makes the type name visible outside its module, but its fields and methods remain private unless they are individually given a visibility modifier.

Visibility Modifiers on Structs, Fields, and Methods

Modifier Who Can Access the Item / Field / Method
(none — default) Only the defining module and its descendant submodules
pub(self) Identical to default private visibility (current module and descendants)
pub(super) The immediate parent module and all of its descendants
pub(in crate::path) The specified ancestor module crate::path and its descendants
pub(crate) Any module anywhere inside the current crate, but hidden from external crates
pub Publicly accessible to any module and (if the module path is exported) external crates
Visibility Scopes Inside a Crate:

  crate root (lib.rs)                  <-- `pub` (external) & `pub(crate)` (crate-wide)
   └── mod network                     <-- `pub(in crate::network)`
        └── mod connection             <-- `pub(super)` (visible to `network`)
             └── struct Socket         <-- private (visible to `connection` + children)
                  └── mod tls          <-- child modules can ALWAYS see parent's private items!

Struct Visibility vs. Field Visibility

A struct's fields can mix visibility levels freely:

mod catalog {
    pub struct Product {
        pub id: u64,               // Public: anyone can read or write `product.id`
        pub name: String,          // Public: anyone can read or write `product.name`
        pub(crate) sku: String,    // Crate-visible: accessible anywhere in this crate
        cost_cents: u64,           // Private: accessible only inside `mod catalog`
    }

    impl Product {
        // Public constructor required because `cost_cents` is private
        pub fn new(id: u64, name: &str, sku: &str, cost_cents: u64) -> Self {
            Self {
                id,
                name: String::from(name),
                sku: String::from(sku),
                cost_cents,
            }
        }

        // Public method exposing a calculated value from the private field
        pub fn retail_price_cents(&self) -> u64 {
            self.cost_cents * 2
        }

        // Private helper method (omits `pub`)
        fn validate_cost(&self) -> bool {
            self.cost_cents > 0
        }

        pub fn is_valid(&self) -> bool {
            self.validate_cost() && !self.name.is_empty()
        }
    }
}

fn main() {
    let mut item = catalog::Product::new(10, "Mechanical Keyboard", "KB-87", 45_00);

    // Public fields (`id`, `name`) and `pub(crate)` fields (`sku`) are accessible here:
    item.name.push_str(" Pro");
    println!(
        "#{} {} (SKU: {}) -> Retail: {} cents (valid: {})",
        item.id,
        item.name,
        item.sku,
        item.retail_price_cents(),
        item.is_valid()
    );
}
#10 Mechanical Keyboard Pro (SKU: KB-87) -> Retail: 9000 cents (valid: true)

Compile Error When Accessing a Private Field or Method (E0616 / E0624)

Attempting to read a private field (item.cost_cents) or call a private method (item.validate_cost()) from outside the defining module produces a compile-time error:

// ❌ does not compile
mod vault {
    pub struct Key {
        secret: u64,
    }

    impl Key {
        pub fn new(secret: u64) -> Self {
            Self { secret }
        }

        fn raw_secret(&self) -> u64 {
            self.secret
        }
    }
}

fn main() {
    let k = vault::Key::new(999);
    println!("{}", k.secret);
    println!("{}", k.raw_secret());
}
error[E0616]: field `secret` of struct `vault::Key` is private
  --> src/main.rs:19:22
   |
19 |     println!("{}", k.secret);
   |                      ^^^^^^ private field

error[E0624]: method `raw_secret` is private
  --> src/main.rs:20:22
   |
11 |         fn raw_secret(&self) -> u64 {
   |         --------------------------- private method defined here
...
20 |     println!("{}", k.raw_secret());
   |                      ^^^^^^^^^^ private method

Tuple Struct Field Visibility

Tuple struct fields (struct Pair(u32, u32);) are also private by default. Marking the struct pub struct Pair(u32, u32); exposes the type name Pair, while pub struct Pair(pub u32, pub u32); also makes the positional fields .0 and .1 and the tuple-struct constructor Pair(a, b) public.