Reputation: 107
Uncompilable version:
fn main() {
let v = vec![1, 2, 3, 4, 5, 6];
let mut b = Buffer::new(v.as_slice());
let r1 = b.read();
let r2 = b.read();
out2(r1, r2);
}
struct Buffer<'a> {
buf : &'a [u8],
pos : usize,
}
fn out2(a: &[u8], b: &[u8]){
println!("{:#?} {:#?}", a, b);
}
impl<'a> Buffer<'a> {
fn new(a : &'a [u8] ) -> Buffer<'a> {
Buffer { buf: (a), pos: (0) }
}
fn read(&'a mut self) -> &'a [u8] {
self.pos += 3;
&self.buf[self.pos - 3..self.pos]
}
}
Compiled successfully version
fn main() {
let v = vec![1, 2, 3, 4, 5, 6];
let mut b = Buffer::new(v.as_slice());
let r1 = b.read();
let r2 = b.read();
out2(r1, r2);
}
struct Buffer<'a> {
buf : &'a [u8],
pos : usize,
}
fn out2(a: &[u8], b: &[u8]){
println!("{:#?} {:#?}", a, b);
}
// a > b
impl<'b, 'a : 'b> Buffer<'a> {
fn new(a : &'a [u8] ) -> Buffer<'a> {
Buffer { buf: (a), pos: (0) }
}
fn read(&'b mut self) -> &'a [u8] {
self.pos += 3;
&self.buf[self.pos - 3..self.pos]
}
}
Both r1 r2 are also hold the partial reference of buffer. And neither held mut ref.
The most difference part is that read function's return lifetime is longer than &mut self
.
But I can't understand why.
Upvotes: 0
Views: 54
Reputation: 71450
The second snippet is equivalent to the following:
impl<'a> Buffer<'a> {
fn read<'b>(&'b mut self) -> &'a [u8] {
self.pos += 3;
&self.buf[self.pos - 3..self.pos]
}
}
Basically, &'a mut self
where 'a
is defined in the struct is almost always wrong. You say the struct needs to be borrowed for as long as the data it holds. Since the data it holds exists from the creation of the instance to its end, so does this borrow. Basically, you say we can use this method only once.
The second snippet, on the other hand, takes a fresh, smaller lifetime on self
and therefore can be called multiple times.
Upvotes: 1