2015-11-30 32 views
5

我正在写一个程序,该程序写入文件并旋转它现在正在写入的文件。当我检查旋转文件时,我似乎无法更改该文件,因为它是由我的结构借用的。即使我drop结构的实例,我似乎无法重新获得该文件的所有权来重新命名它。 这里是我的example“旋转变量时无法移出变量,因为它是借来的”

use std::fs::File; 
use std::io::{Write}; 
use std::mem::{drop}; 

pub struct FileStruct<W: Write> { 
    pub writer: Option<W>, 
} 

impl <W: Write> FileStruct<W> { 
    pub fn new(writer: W) -> FileStruct<W> { 
     FileStruct { 
      writer: Some(writer), 
     } 
    } 
} 

fn main() { 
    let mut file = File::create("tmp.txt").unwrap(); 
    let mut tmp = FileStruct::new(&mut file); 
    loop { 
     if true { //will be time based if check 
      drop(tmp); 
      drop(file); 
      file = File::create("tmp2.txt").unwrap(); 
      tmp = FileStruct::new(&mut file); 
     } 
     // write to file 
    } 
} 

我知道我能得到这个通过移动文件创建到的FileStructnew函数调用,而不必一个中间变量,file工作,但我想知道为什么会这样方法,我强制删除所有变量引用应返回的所有变量不起作用。

+0

你是否需要if-block之外的'tmp'?如果你不这样做,那么你可以在重新分配'file'前确保借用已经结束。 – fjh

+0

我是。这个想法是我正在循环中写入数据,if块是要更改输出文件。 if块意味着我决定是否应该更改'file'。 –

回答

6

由于the std::mem::drop documentation说,

虽然这确实调用参数的实施Drop,也不会释放任何借入,借入作为基于词法范围。

因此,即使您拨打dropfile仍然会继续借用。

+0

下面是关于可能的非词汇范围的一些信息:https://github.com/rust-lang/rfcs/issues/811 –

2

丢失tmp没有“释放借入”file,因为借用在词汇范围内。只要程序执行位于包含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 
} 

这里的技巧是给定一个共同参照RefCell<T>你可以(最终)得到一个&mut T通过borrow_mut()。编译时借用检查器很高兴,因为我们只在表面上使用共享引用,可以像这样共享file。通过在运行时检查内部T是否已被可变借用,可以避免可变的混叠。

相关问题