Common Patterns
New
Idea: Use an associated function as a type constructor.
#![allow(unused)] fn main() { struct MyType { value: Vec<u32> } impl MyType { /// Create a new [`MyType`]. fn new() -> Self { MyType { value: Vec::new() } } } // A new instance of `MyType` let my_class = MyType::new(); }
Newtype
Idea: Wrap an existing type in a struct to form a new type.
This allows you to use Rust's type checker to ensure that the correct type is used.
#![allow(unused)] fn main() { struct AccountId(u64); let account_id = AccountId(0x1234567812345678); }
Block expressions
Idea: Scope temporary variables in a block expression and return the result
#![allow(unused)] fn main() { use std::sync::{Arc, Mutex}; use std::thread; let counter = Arc::new(Mutex::new(0u32)); let t = { // Temporary variables let counter = Arc::clone(&counter); // Block return value thread::spawn(move || { *counter.lock().unwrap() += 1; }) }; t.join().unwrap(); }
Inner
Idea: Store a type's internal state in a private struct.
#![allow(unused)] fn main() { /// Public facing type. pub struct Public(Inner); /// Public API. impl Public { pub fn new() -> Self { Public(Inner { state: 0 }) } } /// Private inner state. struct Inner { state: u32 } /// Private API. impl Inner { fn increment(&mut self) { self.state += 1; } } }