“cannot move out of variable because it is borrowed” when rotating variables

前端 未结 2 913
无人共我
无人共我 2020-12-20 18:53

I am writing a program that writes to a file and rotates the file it\'s writing to every now and then. When I check to rotate the file, I can\'t seem to change the file sinc

2条回答
  •  半阙折子戏
    2020-12-20 19:34

    Dropping tmp does not "release the borrow" of file because borrowing is lexically scoped. It's "active" as long as the program execution is within the lexical scope that contains tmp even if you drop it. What you intended to do might be possible in the future if/once "non-lexical scopes" are supported. Until then, you can make it work with RefCell:

    use std::cell::RefCell;
    use std::io::{ self, Write };
    
    /// wraps a reference to a RefCell
    struct RefCellWriteRef<'a, W: 'a>(&'a RefCell);
    
    /// 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 {
            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> = 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
    }
    

    The trick here is that given a shared reference to a RefCell you can (eventually) get a &mut T via borrow_mut(). The compile-time borrow checker is pleased because we only use a shared reference on the surface and it's OK to share file like that. Mutable aliasing is avoided by checking at runtime whether the internal T has already been mutably borrowed.

提交回复
热议问题