2013-08-06 74 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); 

但爲什麼會失敗?可變和不可變指針的範圍是截然不同的,它們是不同的表達式。它對我來說看起來像是一種錯誤,但我只是想確保我在這裏不會錯過任何東西。

回答

1

了一個錯誤:#6268

這是因爲借用檢查器沒有適當地考慮嵌套方法調用:嵌套調用應該等同於臨時代碼(因此應該是有效的)。

+0

非常感謝,這就是我的想法。我應該在bug追蹤器上搜索它。 –

2

通過引入temp你已經改變了運算順序:先計算some_method(),然後釋放self,然後得到了一個可變引用的selfsome_field

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

是的,據我所知,可變引用不能與其他引用同時使用。但是(就我所見),引用作爲方法參數的用法實際上並不是這些引用的用法。在計算這個參數之後,在下一個參數開始計算之前,爲什麼'ggg'調用中的可變指針不能被釋放?表達式導致參數值是完全獨立的,不應該有任何類型的範圍,而顯然現在有類似的範圍。 –

+0

主函數體不知道foo.ff()不訪問foo.a,因此禁止調用foo.ff(),直到釋放gug之後的&mut foo.a。 – stepancheg

+0

這就是我的觀點,爲什麼'&mut foo.a'只有在'ggg'調用之後纔會被釋放?它是獨立表達,它不應該能夠在圓括號內引入範圍類型。 –