我正在疯狂地试图围绕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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望事实tmpSlice在它自己的范围内允许我self.buf事后借用但似乎借用检查员不同意,因为它说tmpSlice借款在fn fetch范围内结束.
当然它不同意,因为生命周期tmpBuf不会在内部块中结束.clone()在切片上调用返回该切片的副本,即指针和长度的副本.对于所有意图和目的,返回的切片tmpSlice.clone()等效tmpSlice,包括其生命周期.因为您将其分配给tmpBuf外部作用域,所以它自然比内部块的作用域更长.
实际上,如果Rust允许它,你的代码就会中断 - clone_from_slice()源和目标可能会重叠.例如,如果self.tail是0和self.head是,10那么源和目的地完全重叠.
不幸的是,没有办法创建一个在运行时确定大小的固定大小的堆栈数组,所以解决这个问题的唯一方法是通过调用to_owned()或to_vec()在切片上分配数据来获取Vec<u8>.
或者,您可以分配第二个固定大小的数组,该数组保证不小于结构中的数组,并将其用作临时空间.你需要使用clone_from_slice()两次.