2013-08-06 3 views
2

이상한 대출 확인 :나는 대략 다음과 같은 코드가 실패

그것은 다음과 같은 메시지와 함께 실패
let val = util::replace(&mut self.some_field[i], self.some_method()); 

:

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 temp = self.some_method(); 
let val = util::replace(&mut self.some_field[i], temp); 

하지만 왜 실패하나요? 변경할 수있는 포인터와 변경 불가능한 포인터를 구분하는 범위는 서로 다른 표현식입니다. 그것은 나에게 버그의 종류처럼 보이지만, 나는 단지 내가 여기에 뭔가를 놓치지 않고 있는지 확인하고 싶다. 다음 self 발매 먼저 some_method() 계산하고 selfsome_field에 가변 기준을 얻었다 :

답변

1

버그가입니다 : #6268.

차용 검사기가 아직 중첩 된 메소드 호출을 제대로 고려하지 않았기 때문에 중첩 호출은 임시 (따라서 유효해야 함) 코드와 동일해야합니다.

+0

대단히 고마워, 내가 생각했던거야. 내가 버그 추적기에서 찾았어야 했어. –

2

temp를 도입함으로써이 계산 순서를 변경했습니다.

녹이 다른 참조와 함께 변경 가능한 참조를 유지하는 것을 허용하지 않습니다 (변경 가능 또는 변경 불가능). 간단한 예를 참조하십시오

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 
} 
+0

예, 변경할 수있는 참조를 다른 참조와 동시에 사용할 수 없음을 이해합니다. 그러나 (필자가 보았 듯이) 메소드 매개 변수로서 참조를 사용하는 것은 실제로 이러한 참조를 동시에 사용하지는 않습니다. 왜 당신의'ggg' 호출에서 mutable 포인터는이 인수가 계산 된 후 그리고 다음 인수가 계산되기 전에 해제 될 수 없습니까? 매개 변수 값을 초래하는 표현식은 완전히 독립적입니다. 범위가 실제로는 존재하지 않아야하며, 현재 범위와 비슷한 것이 있습니다. –

+0

주 함수 본문에서는 foo.ff()가 foo.a에 액세스하지 못하기 때문에 foo.ff() 호출은 ggg 이후의 & mut foo.a가 릴리스 될 때까지 금지됩니다. – stepancheg

+0

그것이 왜'& mut foo.a'가'ggg' 호출 후에 만 ​​풀리는 이유입니까? 그것은 독립적 인 표현이며, 괄호 안의 범위를 소개해서는 안됩니다. –