我有一个带有两个向量的结构,它在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.b
的可变借款和f.a
的不变借款?TwoArrays
时,为什么不会发生这种情况?它只发生在我作为Arc<Mutex<TwoArrays>>
传递它当你打开LockResult
时,你得到一个MutexGuard
,而不是直接TwoArrays
。你可以使用它,好像它是一个TwoArrays
,因为它实现了Deref
和DerefMut
。
当你尝试编写2个循环时,你会尝试同时使用deref
和deref_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;
}
}
}
您可以在结构中访问两个向量,如下所示:
use std::mem;
#[derive(Debug)]
pub struct TwoArrays {
pub a: Vec<i32>,
pub b: Vec<i32>,
}
fn add_arrays(mut foo: TwoArrays) {
let a = foo.a.clone();
let mut b = foo.b.clone();
for i in a.iter() {
let mut index = 0;
for _j in b.iter_mut() {
let mut new_value = i.clone() + foo.b[index as usize].clone();
mem::swap(&mut foo.b[index as usize], &mut new_value);
index = index + 1;
}
}
println!("Arrays A: {:?}", &foo.a);
println!("Arrays A: {:?}", &foo.b);
}
fn main() {
let a = vec![1i32, 2i32, 3i32];
let b = vec![4i32, 5i32, 6i32];
let two_arrays = TwoArrays { a, b };
// let foo = Arc::new(Mutex::new(two_arrays));
add_arrays(two_arrays);
}
为什么有f的不可变借款?
因为你试图用iter()
迭代它而不是iter_mut()
当我直接传递TwoArrays时,为什么不会发生这种情况?它只发生在我作为
Arc<Mutex<TwoArrays>>
传递它
您可以将其作为裸结构传递,而无需使用带示例代码的Arc<Mutex<>>
。
如果您坚持使用Arc<Mutex<>>
通过原子引用传递相同的对象,则可以将函数签名更改为以下内容:
fn add_arrays(mut foo: Arc<Mutex<TwoArrays>>)
你需要lock()
并从Arc
获得以下参考:
let foo = foo.lock().unwrap();