tha*_*028 3 file rust borrowing
我正在尝试提取.tar.bz文件(或.tar.whatever),并且还能够获得xx%进度报告.到目前为止我有这个:
pub fn extract_file_with_progress<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let path = path.as_ref();
let size = fs::metadata(path)?;
let mut f = File::open(path)?;
let decoder = BzDecoder::new(&f);
let mut archive = Archive::new(decoder);
for entry in archive.entries()? {
entry?.unpack_in(".")?;
let pos = f.seek(SeekFrom::Current(0))?;
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
想法是用来pos/size获得百分比,但编译上面的函数会让我错误cannot borrow f as mutable because it is also borrowed as immutable.我理解错误的含义,但我并没有真正使用它f作为可变的; 我只使用搜索功能来获取当前位置.
有没有办法解决这个问题,要么强制编译器忽略可变借用,要么以某种不可变的方式获取位置?
文件有点特别.通常的read()和seek()和write()的方法(所定义的Read,Seek和Write性状)取self由可变引用:
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
fn seek(&mut self, pos: SeekFrom) -> Result<u64>
fn write(&mut self, buf: &[u8]) -> Result<usize>
Run Code Online (Sandbox Code Playgroud)
但是,所有提到的特征也是为了实现&File,即对文件的不可变引用:
因此,即使您只对文件具有只读引用,也可以修改文件.对于这些实现,Self类型是&File,因此self通过可变引用接受实际上意味着接受&mut &File对文件的引用的可变引用.
您的代码传递&f给BzDecoder::new(),创建一个不可变的借用.后来你打电话f.seek(SeekFrom::Current(0)),这传递f给seek通过可变引用.但是,这是不允许的,因为您已经有一个不可变的借用文件.解决方案是使用Seek实现&File代替:
(&mut &f).seek(SeekFrom::Current(0))
Run Code Online (Sandbox Code Playgroud)
或者稍微简单一点
(&f).seek(SeekFrom::Current(0))
Run Code Online (Sandbox Code Playgroud)
这只会创建第二个不可变借用,这是Rust的引用规则所允许的.
我创建了一个游乐场示例,证明这是有效的.如果你替换你(&f),f你会得到你最初得到的错误.
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |