Yun7k
Yun7k

Reputation: 107

Can someone explain this lifetime code snippet?

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

Answers (1)

Chayim Friedman
Chayim Friedman

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

Related Questions