6 votes

Remplacer le contenu d'un RwLockWriteGuard

Supposons le code suivant :

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

( aire de jeux )

Comment faire pour que la fonction filter_out_values travail ?

7voto

hellow Points 7534

La circonstance particulière est que votre T n'est pas clonable, vous ne pouvez donc pas utiliser la fonction guard.iter().filter(...).cloned().collect() .

Je vois ici deux options.

  1. Au lieu de RwLock<Vec<NotCloneable>> vous pouvez utiliser RwLock<Option<Vec<NotCloneable>>> et utiliser ensuite Option::take() pour obtenir la valeur de la RwLock se tenait et s'en allait None

  2. Vous pouvez utiliser std::mem::replace() pour obtenir le vec de la garde sans déclencher l'erreur, car il n'est pas possible de laisser la valeur du RwLock dans un état indéfini, où il ne détient aucune valeur

    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()); } }

( aire de jeux )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X