Hi,
I am reading the Rust's github repo to learn some idoms because I think it's the best resource out there to familiarize/learn them in production code.
My take: we have a closure doing something, passed as a mutable element to
fn each_ip(f: &mut dyn FnMut(SocketAddr)) {...}
which expects a mutable function (here a closure) that will be dynamically dispatched depending on what it is. Also, this callback has its state mutable. A kind of callback in other languages.
Am I right?
Maybe I got it wrong, please do not hesitate to correct my understanding
which is different in two ways: each_ip is generic over the function rather than using dynamic dispatch, and it takes the function by value instead of by reference.
The probable reason it is written the way it is instead is to minimize compile time of the tests; generic functions have to be compiled over again for each specific type they are used with, which can allow optimizations for the specific case, but here is not worth doing since test code only ever runs once.
And then the &mut is because dyn types must be passed by reference (or Box or other pointer type), not because it is needed for functions or provides any benefit itself.
Actually, it is good that you now know that both options exist. &dyn and &mut dyn are lesser used but I might even say they are less used than they should be. The main thing I wanted you to notice by comparing them is that dyn is not required here.
(Oh, and another case where &mut <some function type> comes up is recursive functions that take an FnMut callback. You'll find that for the borrow checker and type checker to be happy, the only way to write them is passing the callback as &mut, whether dyn or not.)
Yes, they do, but they reduce instructions cache pressure which means that if you use dynamic dispatch for the code which is rarely used you make the code which used often faster.