我正在尝试实现一个简单的文件链。不幸的是,我的
BufRead::fill_buf
实现产生了借用检查器错误。
impl BufRead for FileChain {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
loop {
let buf = self.stream.fill_buf()?;
if !buf.is_empty() {
return Ok(buf);
} if let Some(filename) = self.future_files.pop() {
self.stream = BufReader::new(File::open(&filename)?);
} else {
return Ok(&[])
}
}
}
}
error[E0506]: cannot assign to `self.stream` because it is borrowed
40 | fn fill_buf(&mut self) -> io::Result<&[u8]> {
| - let's call the lifetime of this reference `'1`
41 | loop {
42 | let buf = self.stream.fill_buf()?;
| ---------------------- `self.stream` is borrowed here
43 | if !buf.is_empty() {
44 | return Ok(buf);
| ------- returning this value requires that `self.stream` is borrowed for `'1`
45 | } if let Some(filename) = self.future_files.pop() {
46 | self.stream = BufReader::new(File::open(&filename)?);
| ^^^^^^^^^^^ `self.stream` is assigned to here but it was already borrowed
您可以在此处找到完整的类定义(56 行)。
我认为这与已知的借用检查器问题类似,如here、here和here所述。 基本上,检查者认为
buf
参考阻止 stream
发生变化。但是,return buf
和 stream
更新不能同时发生。
现有的解决方案(例如来自这里)不能在这里应用,因为我没有HashMap/Vector,并且我受到
BufRead
API的限制。我也无法使用polonius
,因为我只能使用稳定的功能。
我的问题是:是否可以使用安全代码修改此代码而不牺牲速度?如果这是不可能的,有没有办法使用不安全的代码覆盖借用检查器?
有没有办法使用不安全的代码覆盖借用检查器?
虽然使用 unsafe 不会关闭借用检查器,但它确实允许您绕过它的一些安全措施。例如,这样编译:
fn fill_buf(&mut self) -> io::Result<&[u8]> {
loop {
{
let buf =
unsafe { std::mem::transmute::<_, &'static [u8]>(self.stream.fill_buf()?) };
if !buf.is_empty() {
return Ok(buf);
}
}
if let Some(filename) = self.future_files.pop() {
self.stream = BufReader::new(File::open(&filename)?);
} else {
return Ok(&[]);
}
}
}