Rust切片所有权超出其作用域

3

我正在努力理解一个Rust生命周期问题,感觉自己快疯了。运行以下代码时:

use std::fs::File;
use std::io::Read;
use std::clone::Clone;

const BUFSIZE : usize = 4096;

struct LexBuf<T: Read> {
    f: T,
    buf: [u8; BUFSIZE],
    tail: usize,
    head: usize
}

impl <T : Read> LexBuf<T> {
    fn fetch(&mut self) {
        let keepSize = self.head - self.tail + 1;
        let mut tmpBuf;
        {
            let tmpSlice = &self.buf[self.tail..self.head+1];
            tmpBuf = tmpSlice.clone();
        }
        &mut self.buf[0..keepSize]
            .clone_from_slice(tmpBuf);
        let mut n = self.f
            .read(&mut self.buf[keepSize..]).unwrap();
        if n < BUFSIZE - keepSize {
            self.buf[keepSize+n] = 0;
        }
    }
}

我希望tmpSlice在自己的作用域中,这样我之后就可以借用self.buf,但似乎借用检查器不同意,因为它说tmpSlice的借用在fn fetch作用域结束。


2
clone 不会创建一个拥有所有权的副本,它只是克隆引用,而不是引用指向的内容。你需要使用 to_owned - oli_obk
1个回答

8
当然不行,因为tmpBuf的生命周期并没有在内部块结束。调用切片上的clone()会返回该切片的副本,即指针和长度的副本。就所有意图而言,tmpSlice.clone()返回的切片与tmpSlice相同,包括其生命周期。因为您在外部作用域中将其分配给tmpBuf,所以它自然而然地超出了内部块的范围。
实际上,如果Rust允许这样做,您的代码将会出错- clone_from_slice()源和目标可能重叠。例如,如果self.tail0,而self.head10,那么源和目标完全重叠。
不幸的是,没有办法创建一个大小在运行时确定的固定大小的堆栈数组,因此唯一的解决方法是通过在切片上调用to_owned()to_vec()来在堆上分配数据,以获得Vec<u8>
或者,您可以分配第二个固定大小的数组,保证不小于结构中的数组,并将其用作临时空间。您需要使用两次clone_from_slice()来实现这一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接