MutexGuard 内部的过滤向量无需克隆

问题描述 投票:0回答:1

我有一个锁定的

a
,里面有一个
B
结构的vecotr。我想过滤
a.b
而不克隆
B
结构。 Rust 可以吗?

use std::sync::{Arc, Mutex};

#[derive(Debug)]
struct B {
    n: i64,
}

#[derive(Debug)]
struct A {
    b: Vec<B>
}

fn main() {
    let arc_a = Arc::new(Mutex::new(A {
        b: vec![
            B { n: 1 },
            B { n: 2 },
            B { n: 3 },
            B { n: 4 },
        ]
    }));
    let mut a = arc_a.lock().unwrap();
    a.b = a.b.into_iter().filter(|b| b.n % 2 == 1).collect();
    println!("{:?}", a);
}

在上面的代码示例中,我有一个错误

error[E0507]: cannot move out of dereference of MutexGuard<'_, A>
。有办法解决这个挑战吗?如何正确解决?

rust mutex
1个回答
0
投票

就地改变向量的常见模式,尤其是在处理互斥体时,是使用 Vec::retain() 方法,该方法允许您就地过滤元素,而无需从 MutexGuard 中获取所有权。 keep 方法迭代向量并仅保留指定闭包返回 true 的元素,从而有效地就地过滤向量。请尝试以下操作:

use std::sync::{Arc, Mutex};

#[derive(Debug)]
struct B {
    n: i64,
}

#[derive(Debug)]
struct A {
    b: Vec<B>
}

fn main() {
    let arc_a = Arc::new(Mutex::new(A {
        b: vec![
            B { n: 1 },
            B { n: 2 },
            B { n: 3 },
            B { n: 4 },
        ]
    }));

    {
        // Lock the mutex and get a mutable reference to A.
        let mut a = arc_a.lock().unwrap();
        
        // Use retain to filter the vector in place.
        a.b.retain(|b| b.n % 2 == 1);
    } // The lock is released here as the mutex guard goes out of scope.

    // Print the modified A.
    println!("{:?}", arc_a.lock().unwrap());
}
© www.soinside.com 2019 - 2024. All rights reserved.