Closure as struct member
The following is an example with a closure and a struct that uses it:
struct Calculator<T>
where
T: Fn(f32, f32) -> f32,
{
operation: T,
}
fn main() {
// Define a closure for addition
let add = |a, b| a + b;
// Create an instance of Calculator with the addition closure
let add_calculator = Calculator { operation: add };
// Use the calculator to perform addition
let result = (add_calculator.operation)(5.0, 3.0);
println!("Result of addition: {}", result);
// Define a closure for subtraction
let subtract = |a, b| a - b;
// Create another instance of Calculator with the subtraction closure
let subtract_calculator = Calculator {
operation: subtract,
};
// Use the calculator to perform subtraction
let result = (subtract_calculator.operation)(10.0, 7.0);
println!("Result of subtraction: {}", result);
}
In this example, we have a Calculator
struct that takes a generic type parameter T
, which is expected to be a closure. The closure should take two f32
arguments and return an f32
. The struct has a single field named operation
of type T
.
In the main
function:
- We define a closure
add
that takes twof32
arguments and returns their sum. - We create an instance of the
Calculator
struct calledadd_calculator
, initializing it with theadd
closure. - We use the
add_calculator
to perform addition by invoking the closure with the arguments 5.0 and 3.0. The result is stored in theresult
variable and printed. - Then, we define another closure
subtract
for subtraction and create aCalculator
instance calledsubtract_calculator
with thesubtract
closure. - We use
subtract_calculator
to perform subtraction in a similar manner.
Webdock – Fast Cloud VPS Hosting
How to use closures as fields of structs
In both cases, the operation
field of the Calculator
struct holds a reference to a closure, and we call that closure with appropriate arguments to perform mathematical operations. This demonstrates how Rust allows you to use closures as fields of structs to achieve flexible behaviour.
The two sets of parentheses in the line let result = (subtract_calculator.operation)(10.0, 7.0);
are used to first access and then immediately call the closure stored in the operation
field of the subtract_calculator
.
Here’s the breakdown of what’s happening:
(subtract_calculator.operation)
accesses theoperation
field of thesubtract_calculator
, which holds a closure. This expression evaluates to the closure itself.(10.0, 7.0)
is a tuple containing the two arguments that the closure expects.- The second set of parentheses
(...)(...)
is used to call the closure with the provided arguments.
Why the 2 sets of parentheses on this line though?
let result = (subtract_calculator.operation)(10.0, 7.0);
In Rust, you can call a closure just like you would call a regular function. However, since the closure is stored as a field in a struct, you first need to access the closure by evaluating (subtract_calculator.operation)
and then immediately call it with (10.0, 7.0)
. This syntax allows you to invoke the closure and calculate the result.
Struct with closure – example 2
Let’s give Bob a 20% pay rise using a closure that uplifts x 1.2