在学习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中的文件添加到文件夹中了?
2条答案
按热度按时间u5rb5r591#
首先,对
f
执行&*
操作,这会给你一个共享引用,你不能改变它。相反,可以执行
&mut *
。您还可以进一步简化表达式,通过auto-deref删除括号和星号:第二个问题更加微妙,当你在match arm中指定
UnixFolder::FOLDER(mut folder)
时,mut
会迫使编译器移出folder
,而不是仅仅将其绑定到一个引用,解释 why 是复杂的,而且实际上并不相关(发生的事情是它选择了匹配人体工程学,但你不需要理解这一点).你需要知道的是,你可以只删除mut
,然后folder
将具有&mut UFolder
类型,并且一切都正常。b5buobof2#
您正在移动一个由其他对象拥有的值(枚举)。您可以实现克隆/复制或使用Rc(多标题中的弧)将其 Package ,这样您就可以克隆引用计数而不是值。