Closures in variables do not need type specification, because they are private to functions and are not exposes outside. Instead, we allow the compiler to infer all that information. However, we can add types if we want to.
Sometimes it might be useful to define a closure that calculates some result that
we want to reuse multiple times. We use structs for that.
It’s analogical to
Lazy<T> of .NET C#.
When we ask for a
value(), the first time we do it, closure will be executed.
value() calls will return a cached value of the closure’s result.
When defining closure as a field of a struct, we need to specify its type. In
the case above, the type is
Fn(u32) -> u32.
Closures can capture variables defined outside of the closure:
Functions cannot do that. Captures can be done in three ways, depending on the
Fn... trait being used:
FnOnce- Instances of
FnOncecan be called, but might not be callable multiple times. Because of this, if the only thing known about a type is that it implements
FnOnce, it can only be called once, because it takes ownership of passed arguments.
FnMut- it mutably borrows external values. Sutrait of
Fn- it immutably borrows external values. Sutrait of
Functions can also be passed in place of closures. Function pointers implement
all three closure traits: