替换 RwLockWriteGuard 的内容

hel*_*low 6 rust

让我们假设以下代码:

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正常工作?

hel*_*low 6

这里的特殊情况是,您T的不可克隆,因此您不能使用guard.iter().filter(...).cloned().collect().

我在这里看到两个选项。

  1. 而不是RwLock<Vec<NotCloneable>>你可以使用RwLock<Option<Vec<NotCloneable>>>然后使用Option::take()来获得RwLock持有和离开的价值None

  2. 您可以使用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)

操场