Capturing the Environment
Part of the Logic & Flow section of Coddy's Rust journey — lesson 62 of 66.
One of the most powerful features of closures is their ability to capture and use variables from their surrounding environment. Unlike regular functions, closures can "see" and access variables that exist in the same scope where they're defined.
Here's how environment capture works:
fn main() {
let x = 10;
let my_closure = || {
println!("The value of x is: {}", x);
};
my_closure(); // This will print "The value of x is: 10"
}In this example, the closure captures the variable x from the surrounding scope and uses it inside its body. The closure doesn't need x to be passed as a parameter - it automatically has access to it.
You can also capture variables and use them in calculations:
let multiplier = 3;
let multiply_by_three = |num| num * multiplier;
let result = multiply_by_three(5); // result is 15Challenge
EasyYou will receive two inputs. The first input is a number representing a base price. The second input is a number representing a discount percentage. Create a closure that captures the discount percentage from the environment and calculates the final price after applying the discount. Call the closure with the base price and print the final price.
Requirements:
- Read the first input (base price) and trim whitespace
- Parse it to
f64 - Read the second input (discount percentage) and trim whitespace
- Parse it to
f64 - Create a closure that takes one parameter (the base price) and captures the discount percentage from the surrounding environment
- The closure should calculate the final price using the formula:
base_price - (base_price * discount / 100.0) - Call the closure with the base price
- Print the final price
Input:
- First line: A base price (e.g.,
100.0) - Second line: A discount percentage (e.g.,
20.0)
Output:
- The final price after applying the discount
Cheat sheet
Closures can capture and use variables from their surrounding environment without needing them as parameters.
Basic environment capture:
let x = 10;
let my_closure = || {
println!("The value of x is: {}", x);
};
my_closure(); // Prints "The value of x is: 10"Capturing variables in calculations:
let multiplier = 3;
let multiply_by_three = |num| num * multiplier;
let result = multiply_by_three(5); // result is 15The closure automatically captures multiplier from the surrounding scope and uses it in the calculation.
Try it yourself
use std::io;
fn main() {
// Read the base price
let mut base_price_input = String::new();
io::stdin().read_line(&mut base_price_input).expect("Failed to read line");
let base_price: f64 = base_price_input.trim().parse().expect("Invalid number");
// Read the discount percentage
let mut discount_input = String::new();
io::stdin().read_line(&mut discount_input).expect("Failed to read line");
let discount: f64 = discount_input.trim().parse().expect("Invalid number");
// TODO: Create a closure that captures the discount and calculates the final price
// TODO: Call the closure with the base price
// Print the final price
// println!("{}", final_price);
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Advanced Control Flow
The 'match' ExpressionMatching Multiple ValuesMatching RangesThe 'if let' ExpressionLoops as ExpressionsRecap - Simple Command Parser4Grouping Data with Structs
What is a Struct?Structs OverviewAccessing Struct FieldsMutable StructsStructs as Function ParametersTuple StructsRecap - Create a Book Struct7Handling Errors with 'Result'
What is a 'Result'?Using 'match' with 'Result'is_ok() and is_err()Shortcuts: unwrap and expectThe Question Mark Operator '?'Parsing Strings to NumbersRecap - Safe Division Function10Closures & Anonymous Functions
What is a Closure?Defining a Simple ClosureClosures with ParametersCapturing the EnvironmentRecap - Simple Adder Closure2Introduction to Vectors
What is a Vector?Creating a VectorAdding Elements with pushAccessing Vector ElementsIterating Over a VectorMutable IterationRemoving ElementsRecap - Basic Score Tracker5Key-Value Pairs with Hash Maps
What is a Hash Map?Creating a Hash MapInserting Key-Value PairsAccessing ValuesIterating Over a Hash MapUpdating a ValueRemoving a PairRecap - Word Counter8Project: Simple Item Inventory
Project SetupAdding an ItemChecking StockSelling an ItemPutting it all together