I'm trying to implement the classic make_adder
function which takes an addable thing and returns a closure which takes another addable thing and returns the sum. Here is my attempt:
use std::ops::Add;
fn make_adder<T: Add + Clone>(x: T) -> impl Fn(T) -> T::Output {
move |y| x.clone() + y
}
Because I don't want to restrict T
to be Copy
, I'm calling clone()
inside the closure. I think this also means there will always be one redundant x
captured by the closure as the "prototype". Can I somehow do this better?
Realistically, you cannot avoid this. You never know if the closure will be called another time; you will need to keep the value in case it is. I wouldn't worry about performing the clone until profiling has identified that this is a bottleneck.
In certain cases, you might be able to change your closure type to FnOnce
, which enforces that it can only be called exactly once:
fn make_adder<T>(x: T) -> impl FnOnce(T) -> T::Output
where
T: Add,
{
move |y| x + y
}
In other cases, you might be able to add some indirection to the problem. For example, instead of passing a T
, pass in a closure that generates a T
(presumably not by cloning its own captured variable...). This T
can always be consumed directly:
fn make_adder<T>(x: impl Fn() -> T) -> impl Fn(T) -> T::Output
where
T: Add,
{
move |y| x() + y
}