让我们假设以下代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
(操场)
我如何使该功能filter_out_values正常工作?
这里的特殊情况是,您T的不可克隆,因此您不能使用guard.iter().filter(...).cloned().collect().
我在这里看到两个选项。
而不是RwLock<Vec<NotCloneable>>你可以使用RwLock<Option<Vec<NotCloneable>>>然后使用Option::take()来获得RwLock持有和离开的价值None
您可以使用std::mem::replace(),以获得vec从保护而不触发错误,因为没有办法,你离开rwlock中的价值不确定状态,在它不持有任何价值
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::replace(&mut *guard, vec![]);
*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());
}
}
Run Code Online (Sandbox Code Playgroud)
(操场)