Why accept fn(..)
instead of Fn(...)
in generics in Rust?
My intuition is that
- on one hand if code accepts closure with context ->
Fn()
, but we provide "no context" closurefn(...)
then compiler should optimize forfn(...)
. - on the other hand, maybe there are advantages on actual memory and assembly representation of
fn(...)
(e.g. takes less space, due to no need to store context), that would make us prefer to restrict our generic type to acceptfn(...)
types not `Fn(...) types ?
Therefore:
- When one may want to restrict type to
fn(...)
in generic types? - When it brings difference,
- and what kind of difference?
Below some pseudocodes for inspiration, feel free to polish them , this is not limited to those cases, as maybe memory size difference is better to demonstrate with Vec<dyn fn(X)->Y>
vs Vec<Fn(X)->Y>
(or using unboxed_closures
syntax ;) ).
Sketches, examples, but not limited to those:
// peusdo code
pub struct Foo <F,X,Y>
where
F: fn(X)->Y ,
...
{
fx: F,
}
impl Foo<F,X,Y> where
F: fn(X)->Y,
...
{
pub fn new(foo: F) -> Self;
...
}
// peusdo code
pub struct FooByRef <'a,X,Y>
where
F: &'a dyn fn(X)->Y ,
...
{
fx: F,
}
impl Foo<'a,X,Y> where
F: &'a dyn fn(X)->Y,
...
{
pub fn new(foo: &'a dyn fn(X)->Y) -> Self;
...
}