-
Hi! Thanks for this library, I'm really enjoying it! One thing I'm confused about is what the rationale is for having the function passed to pub fn replace_with<F>(&self, f: F) -> A where F: FnOnce(&mut A) -> A {
let mut state = self.state().lock.write().unwrap();
let new_value = f(&mut state.value);
let value = std::mem::replace(&mut state.value, new_value);
state.notify(true);
value
} If I'm understanding this correctly, the function What's really confusing to me is that if But I don't understand why it would be useful to the caller to receive back the result of the mutation that |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Your assumption is correct. Because the closure must return an owned value, it cannot (directly) return the reference, so it will usually return a completely new value.
Yes, that is one possible use case. But the bigger use case is when the closure needs to mutate the value in order to return a new value. The best example I have is using mutable.replace_with(|value| {
do_something_with_owned_value(value.take())
}) By using But This is admittedly a rare and niche use case... but I designed the APIs to be as flexible as possible. Also, the Mutable APIs try to copy from existing APIs as much as possible. The Note that let value = mutable.lock_mut();
*value = do_something_with(&value); That is equivalent to this: mutable.replace_with(|value| {
do_something_with(value)
}); The advantage of using let value = mutable.lock_mut();
if some_condition(&value) {
*value = do_something_with(&value);
} It's also generally clearer and easier to understand for people who are reading your code. |
Beta Was this translation helpful? Give feedback.
Your assumption is correct. Because the closure must return an owned value, it cannot (directly) return the reference, so it will usually return a completely new value.
Yes, that is one possible use case.
But the bigger use case is when the closure needs to mu…