访问由互斥体锁定的结构中的两个向量

Jon*_*yer 5 rust

我有一个带有两个向量的结构,在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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

循环 A 编译。

  • 为什么 f 上存在不可变借用?
  • 我可以让它只单独借用每个数组吗?也就是说,可变借用f.b和不可变借用f.a?
  • 为什么我直接通过就不会出现这种情况呢TwoArrays?仅当我将其作为Arc<Mutex<TwoArrays>>

Fre*_*ios 4

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

当您尝试编写 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.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)