rust 有人能解释一下这个生存期代码片段吗?

bq9c1y66  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(121)

无法编译的版本:

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] 
    }
}

编译成功版本

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] 
    }
}

两个r1和r2都保持缓冲区的部分参考,并且都不保持mut参考。
最大的区别是read函数的返回生命周期比&mut self长,但是我不明白为什么。

ni65a41a

ni65a41a1#

第二个代码段等效于以下代码:

impl<'a> Buffer<'a> {
    fn read<'b>(&'b mut self) -> &'a [u8] { 
        self.pos += 3;
        &self.buf[self.pos - 3..self.pos] 
    }
}

基本上,&'a mut self在struct中定义的'a几乎总是错误的,你说struct需要被借用的时间和它保存的数据一样长,因为它保存的数据从示例的创建到结束都存在,所以这个借用也是一样的,基本上,你说我们只能使用这个方法一次。
另一方面,第二个代码片段在self上占用较短的新生命周期,因此可以多次调用。

相关问题