Vector Rust`Vec`-无法在`impl`方法中借用`Vec`作为不可变项(错误[E0502])

Vector Rust`Vec`-无法在`impl`方法中借用`Vec`作为不可变项(错误[E0502]),vector,rust,borrowing,Vector,Rust,Borrowing,关于Rust的错误[E0502]的问题有很多答案,但我不能真正理解一个特定的案例。我有一个struct,它的impl方法如下: struct测试{ 测试向量:向量, } impl试验{ //其他方法。。。 fn测试(&mut self)->i32{ self.test\u vec.swap(0,self.test\u vec.len()-1); //其他操作。。。 } } 尝试编译会立即导致错误: 错误[E0502]:无法借用self.test\u vec作为不可变项,因为它也是作为可变项借用

关于Rust的
错误[E0502]
的问题有很多答案,但我不能真正理解一个特定的案例。我有一个
struct
,它的
impl
方法如下:

struct测试{
测试向量:向量,
}
impl试验{
//其他方法。。。
fn测试(&mut self)->i32{
self.test\u vec.swap(0,self.test\u vec.len()-1);
//其他操作。。。
}
}
尝试编译会立即导致错误:

错误[E0502]:无法借用
self.test\u vec
作为不可变项,因为它也是作为可变项借用的

self.test\u vec.swap(0,self.test\u vec.len()-1);
----------------^^^^^^^^^^^^^^^^此处发生不可变借用
|             |
|可变借用稍后由call使用
可变借用发生在这里
谁能解释一下原因吗?看起来我并不是在试图借用self.test\u vec在那里,我正在传递
usize
类型
len()
调用的结果。另一方面:

fn测试(&mut self)->i32{
让last_index=self.test_vec.len()-1;
自测试向量交换(0,最后一个索引);
//其他操作。。。
}

使用临时变量,它可以按预期工作,这让我想到
len()
调用在到达
交换
后会以某种方式进行计算,从而被借用?我没有看到一些东西是因为语法糖吗?

您必须以编译器的方式来考虑这一点。当你写作时:

self.test_vec.swap(0, self.test_vec.len() - 1);
编译器看到的内容:

let temp1 = &mut self.test_vec;      // Mutable borrow of self.test_vec
let temp2 = &self.test_vec;          // (ERROR!) Shared borrow of self.test_vec for use on getting the length
let temp3 = Vec::len(temp2) - 1; 
Vec::swap(temp1, 0, temp3);
如您所见,您正在借用self.test_vec,然后尝试获取长度,这是另一个借用。由于第一次借用是可变的并且仍然有效,因此第二次借用是非法的

使用临时变量时,实际上是在重新排列借阅顺序,因为
self.test\u vec.len()
在下一个可变借阅之前终止借阅,所以没有冲突


您可以争辩说,编译器应该能够看到您的代码是正确的(如果以正确的方式解释),但编译器显然还不够聪明,无法做到这一点。

感谢您的解释。但是,为什么在
self.test_vec.len()-1
借用过程中实际发生了?我自然希望操作顺序首先计算向量的长度,然后调用函数作为
Vec::swap(&mut self.test_Vec,0,x-1)
。这个问题基本上与
Vec::swap()无关。首先创建一个临时变量(我们看不到),用于保存
和mut self.test\u vec
,然后创建一个临时变量用于
0
,然后创建一个临时变量用于
self.test\u vec.len()-1
。这可能不是100%准确,但如果您这样想,很明显,在生成第三个temp变量时,第一个temp变量仍然在范围内。我将编辑我的答案,以显示这一点。这使它更清楚。我已经通过向函数传递可变引用进行了检查,编译器公平地抱怨双可变借用是非法的——这是可以理解的。感谢您花时间描述您的行为!