Rust &引用;无法移出变量,因为它是借用的;旋转变量时

Rust &引用;无法移出变量,因为它是借用的;旋转变量时,rust,borrow-checker,Rust,Borrow Checker,我正在编写一个程序,它会写入一个文件,并时不时地旋转它要写入的文件。当我选中旋转文件时,我似乎无法更改文件,因为它是由我的结构借用的。即使我dropstruct的实例,我似乎也无法重新获得文件的所有权来重命名它。 这是我的: 使用std::fs::File; 使用std::io::{Write}; 使用std::mem::{drop}; 发布结构文件结构{ 酒吧作家:选择, } impl文件结构{ pub fn new(作者:W)->FileStruct{ 文件结构{ 作者:一些(作者), }

我正在编写一个程序,它会写入一个文件,并时不时地旋转它要写入的文件。当我选中旋转文件时,我似乎无法更改文件,因为它是由我的结构借用的。即使我
drop
struct的实例,我似乎也无法重新获得文件的所有权来重命名它。 这是我的:

使用std::fs::File;
使用std::io::{Write};
使用std::mem::{drop};
发布结构文件结构{
酒吧作家:选择,
}
impl文件结构{
pub fn new(作者:W)->FileStruct{
文件结构{
作者:一些(作者),
}
}
}
fn main(){
让mut file=file::create(“tmp.txt”).unwrap();
让mut tmp=FileStruct::new(&mut file);
环路{
如果为true{//将基于时间进行检查
下降(tmp);
放下(文件);
file=file::create(“tmp2.txt”).unwrap();
tmp=FileStruct::new(&mut文件);
}
//写入文件
}
}
我知道我可以通过将文件创建移动到
FileStruct
new
函数调用中,而不是使用中间变量
file
,来实现这一点,但是我想知道为什么我强制删除所有变量引用的方法不起作用。

如前所述

虽然这确实调用了参数的
Drop
,但它不会释放任何借词,因为借词是基于词法范围的


因此,即使您调用
drop
文件
仍将被借用。

drop
tmp
不会“释放
文件
的借用”,因为借用是词汇范围。只要程序执行在包含
tmp
的词法范围内,即使您删除它,它也是“活动的”。如果支持“非词法作用域”,您打算做的事情将来可能会实现。在此之前,您可以使用
RefCell

use std::cell::RefCell;
use std::io::{ self, Write };

/// wraps a reference to a RefCell<W>
struct RefCellWriteRef<'a, W: 'a>(&'a RefCell<W>);

/// implement Write for when W is Write
impl<'a, W: Write + 'a> Write for RefCellWriteRef<'a, W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let mut w = self.0.borrow_mut();
        w.write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        let mut w = self.0.borrow_mut();
        w.flush()
    }
}

fn main() {
    let file: RefCell<Vec<u8>> = RefCell::new(Vec::new());
    // use RefCellWriteRef(&file) instead of &mut file
    let mut tmp = RefCellWriteRef(&file); 
    for iter in 0..10 {
        if iter == 5 {
            drop(tmp);
            file.borrow_mut().clear(); // like opening a new file
            tmp = RefCellWriteRef(&file);
        }
        tmp.write(b"foo").unwrap();
    }
    drop(tmp);
    println!("{}", file.borrow().len()); // should print 15
}
使用std::cell::RefCell;
使用std::io::{self,Write};
///包装对参照单元格的引用
结构RefCellWriteRef(&'a RefCell);
///在W为Write时实现Write

为RefCellWriteRef执行写入是否需要if块外部的
tmp
?如果不这样做,则可以确保在重新分配
文件
之前借用结束。我会这样做。我的想法是在循环中写入数据,if块将更改输出文件。if块用于确定是否应更改
文件
use std::cell::RefCell;
use std::io::{ self, Write };

/// wraps a reference to a RefCell<W>
struct RefCellWriteRef<'a, W: 'a>(&'a RefCell<W>);

/// implement Write for when W is Write
impl<'a, W: Write + 'a> Write for RefCellWriteRef<'a, W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let mut w = self.0.borrow_mut();
        w.write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        let mut w = self.0.borrow_mut();
        w.flush()
    }
}

fn main() {
    let file: RefCell<Vec<u8>> = RefCell::new(Vec::new());
    // use RefCellWriteRef(&file) instead of &mut file
    let mut tmp = RefCellWriteRef(&file); 
    for iter in 0..10 {
        if iter == 5 {
            drop(tmp);
            file.borrow_mut().clear(); // like opening a new file
            tmp = RefCellWriteRef(&file);
        }
        tmp.write(b"foo").unwrap();
    }
    drop(tmp);
    println!("{}", file.borrow().len()); // should print 15
}