rust 无法移出枚举变量

omvjsjqw  于 2022-12-23  发布在  其他
关注(0)|答案(2)|浏览(150)

在学习Rusts臭名昭著的借位检查器的过程中,我无可救药地陷入了困境。我构建了一个松散地表示文件系统的树结构。当我试图借用一个枚举值并试图改变底层值时,我得到了一个我不理解的错误。假设cache_files实际上有一些元素在其中。下面是代码:

enum UnixFile{
    FILE(UFile),
    FOLDER(UFolder)
}

struct UFile {
    name: String,
    parent: Weak<RefCell<UnixFile>>,
    size: usize,
}

struct UFolder {
    name: String,
    parent: Weak<RefCell<UnixFile>>,
    files: Vec<Rc<RefCell<UnixFile>>>,
}

fn main() {
    let root = Rc::new(RefCell::new(
        UnixFile::FOLDER(
            UFolder {
                name: String::from("root"),
                parent: Weak::new(),
                files: vec![],
            })));

    let mut current = root.clone();

    let mut f = &*(*current).borrow_mut();

    let mut cache_files:Vec<Rc<RefCell<UnixFile>>> = Vec::new();

    match f {
        UnixFile::FOLDER(mut folder) => {
            folder.files.append(&mut cache_files);
        },
        UnixFile::FILE(file) => {}
    }
}

这是最终的错误:

error[E0507]: cannot move out of `f` as enum variant `FOLDER` which is behind a shared reference
  --> src/main.rs:43:11
   |
43 |     match f {
   |           ^
44 |         UnixFile::FOLDER(mut folder) => {
   |                          ----------
   |                          |
   |                          data moved here
   |                          move occurs because `folder` has type `UFolder`, which does not implement the `Copy` trait

那么这个错误意味着什么呢?我怎样才能把代码放在一个位置,这样我就可以把cache_files中的文件添加到文件夹中了?

u5rb5r59

u5rb5r591#

首先,对f执行&*操作,这会给你一个共享引用,你不能改变它。
相反,可以执行&mut *。您还可以进一步简化表达式,通过auto-deref删除括号和星号:

let mut f = &mut *current.borrow_mut();

第二个问题更加微妙,当你在match arm中指定UnixFolder::FOLDER(mut folder)时,mut会迫使编译器移出folder,而不是仅仅将其绑定到一个引用,解释 why 是复杂的,而且实际上并不相关(发生的事情是它选择了匹配人体工程学,但你不需要理解这一点).你需要知道的是,你可以只删除mut,然后folder将具有&mut UFolder类型,并且一切都正常。

b5buobof

b5buobof2#

您正在移动一个由其他对象拥有的值(枚举)。您可以实现克隆/复制或使用Rc(多标题中的弧)将其 Package ,这样您就可以克隆引用计数而不是值。

相关问题