让我们假设以下代码:
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
如何使功能filter_out_values
工作?
答案 0 :(得分:4)
这里的特殊情况是您的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());
}
}