我正在为一种玩具语言编写编译器,我希望能够检查每个文件上的错误。我有一个MooFile结构,它有一个Vec<anyhow::Error>,当遇到错误时,我会在那里放置错误。现在,我想遍历这些文件,获取错误,并将其压缩到一个单独的vec中,以便从编译器返回,但我遇到的是借阅检查器。我将发布我的各种尝试,但他们总是遇到类似的问题。
fn compile(&mut self) -> Result<(), Vec<Error>> {
...
// Check for errors
let has_errors = self.files
.iter()
.map(|file| file.has_errors())
.reduce(|acc, value| acc | value)
.unwrap_or(false);
if has_errors {
let mut errors = vec![];
self.files
.iter()
.for_each(|&mut file| errors.append(&mut file.errors));
Err(errors)
} else {
Ok(())
}
}error[E0596]: cannot borrow `file.errors` as mutable, as it is behind a `&` reference
--> src\lib.rs:62:48
|
62 | .for_each(|file| errors.append(&mut file.errors));
| ---- ^^^^^^^^^^^^^^^^ `file` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| |
| help: consider changing this to be a mutable reference: `&mut MooFile`fn compile(&mut self) -> Result<(), Vec<Error>> {
...
// Check for errors
let has_errors = self.files
.iter()
.map(|file| file.has_errors())
.reduce(|acc, value| acc | value)
.unwrap_or(false);
if has_errors {
let mut errors = vec![];
self.files
.into_iter()
.for_each(|mut file| errors.append(&mut file.errors));
Err(errors)
} else {
Ok(())
}
}error[E0507]: cannot move out of `self.files` which is behind a mutable reference
--> src\lib.rs:63:13
|
63 | self.files
| ^^^^^^^^^^ move occurs because `self.files` has type `Vec<MooFile>`, which does not implement the `Copy` trait
64 | .into_iter()
| ----------- `self.files` moved due to this method callfn compile(&mut self) -> Result<(), Vec<Error>> {
...
// Check for errors
let errors: Vec<Error> = self.files
.iter()
.map(|file| file.errors)
.flatten()
.collect();
if errors.len() > 0 {
Err(errors)
} else {
Ok(())
}
}error[E0507]: cannot move out of `file.errors` which is behind a shared reference
--> src\lib.rs:54:25
|
54 | .map(|file| file.errors)
| ^^^^^^^^^^^ move occurs because `file.errors` has type `Vec<anyhow::Error>`, which does not implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
error: could not compile `moo2` due to previous error我觉得必须有某种惯用的方式来做这种我错过的事情。
发布于 2022-07-06 20:08:42
这些错误大多来自您如何创建迭代器。如果假设x是Vec<Y>
x.iter():消耗&x,创建&Y.x.iter_mut():迭代器,消耗&mut x,创建&mut Y.x.into_iter():迭代器,消耗整个Vec<Y>的所有权,创建拥有Y.的迭代器。
当您需要可变引用( .iter() )时,第一个版本使用.iter_mut()。第二种方法是在需要可变引用( .into_iter() )时使用.iter_mut()。第三种方法使用.iter(),当您试图通过处理文件来声明错误的所有权时(.into_iter(),但是您不能在没有问题的情况下删除self.files )。
这里有一种方法,您可以Clone错误而不将它们从每个file中移出。
let mut errors = Vec::new();
self.files.iter()
.filter(|file| file.has_errors())
.foreach(|file| errors.extend_from_slice(&file.errors));
if has_errors {
return Err(errors)
}
Ok(())或者您可以使用drain将它们放入一个新的Vec中。这个版本也使用any看起来更干净,但效率不高。
if self.files.iter().any(|f| f.has_errors()) {
let mut errors = Vec::new();
for file in &mut self.files {
errors.extend(file.errors.drain(..));
}
return Err(errors)
}
Ok(())https://stackoverflow.com/questions/72888978
复制相似问题