Let's assume the following code:
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo {
value: RwLock<Vec<NotCloneable>>,
}
impl Foo {
// does not work
pub fn filter_out_values(&self) {
let mut guard = self.value.write().unwrap();
*guard = guard.into_iter().filter(|nc| nc.0 != 0).collect();
}
}
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:12:18
|
12 | *guard = guard.into_iter().filter(|nc| nc.0 != 0).collect();
| ^^^^^ cannot move out of borrowed content
(playground)
How do I make the function filter_out_values
work?
The special circumstance here is, that your T
is not Cloneable, therefore you cannot use guard.iter().filter(...).cloned().collect()
.
I see two options here.
Instead of RwLock<Vec<NotCloneable>>
you could use RwLock<Option<Vec<NotCloneable>>>
and then use Option::take()
to get the value the RwLock
was holding and leaving None
You could use std::mem::take()
, which is a shortcut for std::mem::replace(v, Default::default())
, to get the vec
from the guard without triggering the error, because there is no way that you leave the value of the RwLock in an undefined state, where it does not hold any value
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo {
value: RwLock<Vec<NotCloneable>>,
}
impl Foo {
pub fn filter_out_values(&self) {
let mut guard = self.value.write().unwrap();
let vec = std::mem::take(&mut *guard);
*guard = vec.into_iter().filter(|nc| nc.0 != 0).collect();
}
}
pub struct Foo1 {
value: RwLock<Option<Vec<NotCloneable>>>,
}
impl Foo1 {
pub fn filter_out_values(&self) {
let mut guard = self.value.write().unwrap();
let vec = guard.take();
*guard = Some(vec.unwrap().into_iter().filter(|nc| nc.0 != 0).collect());
}
}
(playground)
While the other answer is correct, in this case, I'd recommend you to use Vec::retain()
:
impl Foo {
pub fn filter_out_values(&self) {
let mut guard = self.value.write().unwrap();
guard.retain(|nc| nc.0 != 0);
}
}
It will also be faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With