Method Chaining
Part of the Object Oriented Programming section of Coddy's Rust journey — lesson 6 of 61.
So far, our mutable methods have modified the struct and returned nothing. But what if we want to call several methods in a row on the same instance? By returning a reference to self, we enable method chaining—a pattern where multiple method calls flow together in a single expression.
The key is having your &mut self methods return &mut Self:
struct Config {
debug: bool,
timeout: u32,
}
impl Config {
fn new() -> Config {
Config { debug: false, timeout: 30 }
}
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
Each method modifies the struct, then returns self—a mutable reference back to the same instance. This allows the next method call to continue working on it immediately:
fn main() {
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
println!("Debug: {}, Timeout: {}", config.debug, config.timeout);
// Output: Debug: true, Timeout: 60
}
Instead of writing three separate statements, we configure everything in one fluid line. This "builder-style" pattern is especially useful when setting up objects with many optional settings, making your code more concise and readable.
Challenge
EasyCreate a TextStyle struct with three fields: bold (bool), italic (bool), and size (u32).
Add an implementation block for TextStyle with the following:
new— an associated function that returns aTextStylewithboldset tofalse,italicset tofalse, andsizeset to12set_bold— takes&mut selfand aboolvalue, sets the bold field, and returns&mut Selffor chainingset_italic— takes&mut selfand aboolvalue, sets the italic field, and returns&mut Selffor chainingset_size— takes&mut selfand au32value, sets the size field, and returns&mut Selffor chaining
You will receive three inputs:
- First line: bold setting (
trueorfalse) - Second line: italic setting (
trueorfalse) - Third line: font size (u32)
Create a mutable TextStyle using new, then use method chaining to apply all three settings in a single expression. Print the final state in the format shown below.
Expected output format:
Bold: {bold}, Italic: {italic}, Size: {size}Cheat sheet
Methods that take &mut self can return &mut Self to enable method chaining:
impl Config {
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
This allows multiple method calls in a single expression:
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
Each method modifies the struct and returns a mutable reference to the same instance, allowing the next method to continue working on it immediately.
Try it yourself
use std::io;
// TODO: Define the TextStyle struct here
// TODO: Add the implementation block for TextStyle with:
// - new() associated function
// - set_bold() method
// - set_italic() method
// - set_size() method
fn main() {
let mut input = String::new();
// Read bold setting
io::stdin().read_line(&mut input).expect("Failed to read line");
let bold: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// Read italic setting
io::stdin().read_line(&mut input).expect("Failed to read line");
let italic: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// Read size setting
io::stdin().read_line(&mut input).expect("Failed to read line");
let size: u32 = input.trim().parse().expect("Invalid u32");
// TODO: Create a mutable TextStyle using new(), then use method chaining
// to apply all three settings in a single expression
// TODO: Print the result in the format: Bold: {bold}, Italic: {italic}, Size: {size}
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Methods and Behavior
Intro Implementation BlocksThe Self ParameterMutable MethodsAssociated FunctionsMultiple Implementation BlocksMethod ChainingRecap - Rectangle Actions4Project: Virtual Pet
Defining the PetFeeding the Pet7Standard Traits
The Debug TraitThe Display TraitClone and CopyEquality TraitsRecap - Printable Point10Project: Document System
The Draw TraitText Component2Encapsulation and Modules
Modules BasicsThe Public KeywordPrivate FieldsGettersSettersRecap - Secure Locker5Generics
Generic StructsGeneric MethodsMultiple Generic TypesGeneric FunctionsRecap - Coordinate Point8Traits as Bounds
Trait Bounds SyntaxMultiple BoundsThe Where ClauseReturning Types with TraitsRecap - Generic Printer11Design Patterns in Rust
Newtype PatternCompositionThe Drop TraitFrom and IntoRecap - Smart Pointer Mock