我發現Rust破壞了一些舊的代碼,我決定修復它。令人遺憾的是,看起來終身參考文獻已經發生了很大變化,出現了一些奇怪的事情。 字段Counter.data
是不相關的,它只是用來顯示我使用的一些數據,它是對通用內容的引用。Rust and old iterator pattern中的生存期
下面是代碼:
struct Counter <'c, T: 'c> {
val: u32,
data: &'c T
}
struct CounterIterator<'c, T:'c> {
iter: &'c mut Counter<'c, T>,
num: u32
}
impl<'r, T> Iterator<u32> for CounterIterator<'r, T> {
fn next(&mut self) -> Option<u32> {
if self.num == 0 {
None
} else {
self.num -= 1;
self.iter.incr()
}
}
}
impl<'c, T> Counter <'c, T> {
fn new(dataz: &'c T) -> Counter<'c, T> {
Counter {
val: 0u32,
data: dataz
}
}
fn incr(&mut self) -> Option<u32> {
self.val += 1;
println!("{}", self.val);
Some(self.val)
}
fn iter(&'c mut self, num: u32) -> CounterIterator<'c, T> {
CounterIterator {
iter: self,
num: num
}
}
}
fn main() {
let val = 11u;
let mut cnt = Counter::new(&val);
for i in range(0,2u) {
cnt.incr();
}
for i in cnt.iter(3) {
}
cnt.incr(); // <- commenting this out "fixes" the problem
// Otherwise the error is
// note: previous borrow of `cnt` occurs here; the mutable borrow prevents
// subsequent moves, borrows, or modification of `cnt` until the borrow ends
}
什麼是這裏的錯誤呢? 我該如何做到這一點,以便'迭代器'成語在退出循環時結束借入,而不是在其定義的塊的末尾? 另外,明確的生活時間T:'c
做什麼?
爲了記錄我試圖在使用中實現類似於str.chars()
的Iterator API。如果有更好的方法去做,請告訴我。
只是微微評論。儘管我沒有使用這個解決方案,但它是幾個正確的解決方案之一。其他解決方案包括通過使用'Cell'放下可變性,或者等到借用檢查器支持非詞法範圍。 – 2014-09-05 15:34:29
@DanielFath是的,還有其他的方法。還有一個你定義CounterIterator有兩個生命週期(但它有點複雜):http://is.gd/eMsLJd – 2014-09-06 19:14:08
實際上,這是我正在尋找的解決方案。我從來沒有設法使生命時間正確工作。你可以添加它,所以它不會被pastebin /圍欄意外刪除? – 2014-09-06 20:44:32