Pointers 奇怪的借阅检查失败

Pointers 奇怪的借阅检查失败,pointers,rust,Pointers,Rust,我大致有以下代码: let val = util::replace(&mut self.some_field[i], self.some_method()); let temp = self.some_method(); let val = util::replace(&mut self.some_field[i], temp); 它失败,并显示以下消息: unrelated.rs:61:65: 61:70 error: cannot borrow `*self` as im

我大致有以下代码:

let val = util::replace(&mut self.some_field[i], self.some_method());
let temp = self.some_method();
let val = util::replace(&mut self.some_field[i], temp);
它失败,并显示以下消息:

unrelated.rs:61:65: 61:70 error: cannot borrow `*self` as immutable because it is also borrowed as mutable
unrelated.rs:61             let val = util::replace(&mut self.some_field[i], self.some_method());
                                                                             ^~~~~
unrelated.rs:61:36: 61:62 note: second borrow of `*self` occurs here
unrelated.rs:61             let val = util::replace(&mut self.some_field[i], self.some_method());
                                                    ^~~~~~~~~~~~~~~~~~~~~~~
我可以通过以下代码修复此问题:

let val = util::replace(&mut self.some_field[i], self.some_method());
let temp = self.some_method();
let val = util::replace(&mut self.some_field[i], temp);

但为什么它会失败呢?可变指针和不可变指针的作用域是不同的,它们是不同的表达式。对我来说,这看起来像是一种错误,但我只是想确保我没有遗漏什么。

通过引入
temp
您已经改变了计算顺序:您首先计算
some_方法()
,然后发布
self
,然后获得对
self
某个字段的可变引用

Rust不允许将可变引用与任何其他引用(可变或不可变)一起持有。请参见更简单的示例:

struct Foo {
    a: int
}

impl Foo {
    fn ff(&self) -> int { 1 }
}

fn fff(a: int, foo: &mut int) { }
fn ggg(foo: &mut int, a: int) { }

fn main() {
    let mut foo = Foo { a: 0 };
    fff(foo.ff(), &mut foo.a); // this call is valid
    ggg(&mut foo.a, foo.ff()); // this is not
}
这是一个错误:


这是因为borrow checker尚未正确考虑嵌套的方法调用:嵌套的调用应该与带有临时的代码等效(因此应该是有效的)。

是的,我理解可变引用不能与其他引用同时使用。但是(在我看来)将引用用作方法参数并不是同时使用这些引用。为什么在计算完此参数之后,在开始计算下一个参数之前,
ggg
调用中的可变指针不能被释放?产生参数值的表达式是完全独立的,实际上不应该有任何类型的作用域,而现在显然有类似的作用域。主函数体不知道foo.ff()不访问foo.a,因此在发布&mut foo.a之前禁止调用foo.ff(),这是在ggg之后。这是我的观点,为什么
&mut foo.a
仅在
ggg
调用后才发布?它是独立的表达式,不应该在括号内引入作用域的类型。它不是独立的,因为指向foo成员的指针(不是值)被传递给
ggg
。所以
foo
的数据在
ggg
内部使用,直到
ggg
结束。非常感谢,这就是我的想法。我应该在bug追踪器上搜索它。