This question already has an answer here:
Error while trying to borrow 2 fields from a struct wrapped in RefCell

(1 个回答)


2年前关闭。




我有一个带有两个向量的结构,它在 Arc<Mutex<TwoArrays>> 中通过一个函数传递。
pub struct TwoArrays {
    pub a: Vec<i32>,
    pub b: Vec<i32>,
}

fn add_arrays(mut foo: Arc<Mutex<TwoArrays>>) {
    let mut f = foo.lock().unwrap();
    //Loop A: compiles
    for i in 0..f.a.len() {
        for j in 0..f.b.len() {
            f.b[j] += f.a[i];
        }
    }
    //Loop B: does not compile
    for i in f.a.iter() {
        for j in 0..f.b.len() {
            f.b[j] += i;
        }
    }
}

当我创建一个使用迭代器的循环,并在其中写入另一个循环(循环 B)时,编译器会提示:

error[E0502]: cannot borrow `f` as mutable because it is also borrowed as immutable

循环 A 编译。
  • 为什么 f 上有一个不可变的借用?
  • 我可以让它只单独借用每个数组吗?也就是说,f.b 的可变借用和 f.a 的不可变借用?
  • 为什么我直接传TwoArrays时不会出现这种情况?只有当我将它作为 Arc<Mutex<TwoArrays>>
  • 传入时才会发生

    最佳答案

    当您打开 LockResult 时,您会得到一个 MutexGuard ,而 而不是 直接是一个 TwoArrays 。您可以像使用 TwoArrays 一样使用它,因为它实现了 DerefDerefMut

    当您尝试编写 2 个循环时,您尝试同时使用 derefderef_mut:这是不可能的:

    pub struct TwoArrays {
        pub a: Vec<i32>,
        pub b: Vec<i32>,
    }
    
    fn add_arrays(mut foo: Arc<Mutex<TwoArrays>>) {
        let mut f = foo.lock().unwrap();
    
        //Loop B: does not compile
        for i in f.a.iter() {
              //  ^~~~~~~~~~~~~~~~~~~ Implicit call to `deref` here.
            for j in 0..f.b.len() {
              //         ^~~~~~~~~~~~ Another implicit call to `deref` here.
                f.b[j] += i;
              // ^~~~~~~~~~~~~~~~~~~~ Implicit call to `deref_mut` here.
            }
        }
    }
    

    如果在执行循环之前 deref_mut 一次,则一切正常:

    use std::{sync::{Arc, Mutex}, ops::DerefMut};
    
    pub struct TwoArrays {
        pub a: Vec<i32>,
        pub b: Vec<i32>,
    }
    
    fn add_arrays(foo: &mut Arc<Mutex<TwoArrays>>) {
        let mut mutex_guard = foo.lock().unwrap();
        let real_two_arrays = mutex_guard.deref_mut();
    
        for i in &mut real_two_arrays.a {
            for j in &real_two_arrays.b {
                *i += *j;
            }
        }
    }
    

    关于rust - 访问由互斥锁锁定的结构中的两个向量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54942045/

    10-10 19:35