Update an element inside MutableVec?
Closed this issue · 2 comments
Is it currently possible to modify an element of a MutableVec
in place? Right now, it seems the only way to achieve this would be to clone the element and then replace it with set
, e.g.:
let lock = my_mutable_vec.lock();
let mut item = lock.get(1).map(|inner| inner.clone()).unwrap();
item.value = new_value;
lock.set(1, old);
Would it be possible to add an update
method which also sends a VecDiff::UpdateAt
to the connected signals? Then we could just write:
my_mutable_vec.lock().update(1, |item| item.value = new_value);
Vec
and slice
don't have an update method, because it's actually really tricky to implement in a safe way (if the closure panics).
I could implement get_mut
with just a usize
, but I'm not sure if that's future-compatible with SliceIndex
.
And I think it's a bit of a footgun to implement get_mut
, because it's not clear to the user that it's actually cloning the value repeatedly.
Note that if you want to update an inner part of the element (like the value
field in your example), then your best option is to make it into a Mutable
:
struct Foo {
value: Mutable<u32>,
}
struct Bar {
foos: MutableVec<Arc<Foo>>,
}
Now you can easily do this:
let lock = bar.foos.lock_ref();
lock[1].value.set(new_value);
This is very idiomatic, and will generally be quite fast (since it gives you fine-grained updates). You can also store multiple Mutable
s in the struct (one Mutable
per field), which is also very idiomatic. MutableVec
and Mutable
are designed to complement each other very well.
The Arc
is optional, but it means that the _cloned
methods will be very fast.