问题描述
我正在尝试遍历 Vec<String>
的文件路径并读取文件的内容。但是,match
语句会引发有关模式中变量的编译器错误。代码如下:
//paths: Vec<String>
//get counts in paths
for path in paths.iter() {
let mut path_result: Result<std::fs::File,std::io::Error>;
let file: std::fs::File;
if path != "-" {
path_result = std::fs::File::open(&path);
}
//match result with error
match path_result {
Ok(path_file) => { file = path_file },Err(e) => {
match e.kind() {
std::io::ErrorKind::NotFound => { println!("{}: No such file or directory",&path) },std::io::ErrorKind::PermissionDenied => { println!("{}: Permission denied",_ => {
println!("{}: UnkNown error",&path);
panic!("unkNown error opening file");
}
}
continue;
}
};
/*get content from file variable*/
}
这是我收到的编译器错误:
error[E0382]: use of moved value
--> src/main.rs:60:16
|
51 | let mut path_result: Result<std::fs::File,std::io::Error>;
| --------------- move occurs because `path_result` has type `std::result::Result<File,std::io::Error>`,which does not implement the `copy` trait
...
60 | Ok(path_file) => { file = path_file },| ^^^^^^^^^ value used here after move
...
75 | }
| -
| |
| value moved here,in prevIoUs iteration of loop
| value moved here,in prevIoUs iteration of loop
error: aborting due to prevIoUs error; 16 warnings emitted
For more information about this error,try `rustc --explain E0382`.
error: Could not compile `test`
To learn more,run the command again with --verbose.
警告与此代码段中未包含的未使用变量有关。
我尝试借用 path_file 变量的内容,但收到相同的错误。我对这种情况的理解是,因为 path_file
块后面没有使用 path_result
和 for
,而且 path_result
在开始时重新绑定,所以即使是如果所有权超出 match
语句的范围。然而,情况似乎并非如此。
解决方法
你不能在 Rust 中使用未初始化的值。此代码不起作用:
// declare path_result here
let mut path_result: Result<std::fs::File,std::io::Error>;
// conditionally initialize it here
if path != "-" {
path_result = std::fs::File::open(&path);
}
// potentially use uninitialized value: error!
match path_result {
上述代码也是您收到 value moved here,in previous iteration of the loop
错误的原因,因为您实际上并未在循环的每次迭代中初始化 path_result
。重构代码以在每次迭代中无条件初始化 path_result
后,它就会编译:
fn example(paths: Vec<String>) {
for path in paths.iter() {
if path == "-" {
println!("skipping un-openable path: -");
continue;
}
let file = match std::fs::File::open(&path) {
Ok(path_file) => path_file,Err(e) => {
match e.kind() {
std::io::ErrorKind::NotFound => {
println!("{}: No such file or directory",&path)
}
std::io::ErrorKind::PermissionDenied => {
println!("{}: Permission denied",&path)
}
_ => {
println!("{}: Unknown error",&path);
panic!("unknown error opening file");
}
}
continue;
}
};
/* get content from file variable */
}
}