RUST / CHAPTER 05
Structs and invariant-preserving methods
IntermediateEncapsulate valid state and make mutation requirements visible.
By the end of this chapter
- Use self and borrowed receivers
- Validate construction and updates
- Distinguish field privacy from immutability
The idea
A struct groups named fields into a domain value. An impl block supplies associated functions and methods, and the receiver explains how the method uses its instance. &self borrows for inspection, &mut self permits mutation, and self consumes the value unless its type supports copying. Choose the receiver from the operation’s ownership contract instead of adding clones to satisfy the compiler blindly.
Private fields help keep invalid state from being constructed outside the defining module. A constructor can return Option or Result when validation fails, and modifying methods should reject invalid changes before mutation. Privacy alone does not validate values; every accepted transition must preserve the invariant. A small query method exposes needed information without granting callers unrestricted access to the internal representation.
struct Stock { remaining: u32 }
impl Stock { fn take(&mut self,n:u32)->bool { if n>self.remaining{return false;} self.remaining-=n; true } }
fn main(){let mut s=Stock{remaining:4}; println!("{}",s.take(5)); println!("{}",s.remaining);}false 4
The guard returns before subtraction, preserving the count when a request is too large.
Try it yourself
Add a constructor and getter to a bounded counter, then reject updates beyond its capacity.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING