I found that Rust broke the old code, and I decided to fix it. Unfortunately, it seems that references to life have changed quite a bit, and something strange is happening. The field Counter.datadoes not matter, it is simply used to show that there is some data that I use, and refers to general material.
Here is the code:
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
}
What is the mistake here? How to do this, so that the Iteratorβs idiom ends with borrowing by the time it leaves the loop, and is it defined at the end of the block? Also, what are the obvious times of life T:'c?
For the record, I am trying to use the Iterator API, similar str.chars()in use. If there is a more robust way to do this, please let me know.