Заменить содержимое RwLockWriteGuard - PullRequest
0 голосов
/ 10 ноября 2018

Давайте предположим следующий код:

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 работать?

1 Ответ

0 голосов
/ 10 ноября 2018

Особое обстоятельство здесь заключается в том, что ваш 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());
    }
}

( детская площадка )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...