str*_*ner 12 error-handling rust
第9 行的?操作符工作正常,但如果我在第 19 行的相同类型上使用相同的逻辑,它就会崩溃。
use std::error::Error;
use walkdir::WalkDir;
fn main() -> Result<(), Box<dyn Error>> {
let valid_entries = WalkDir::new("/tmp")
.into_iter()
.flat_map(|e| e)
.flat_map(|e| {
let name = e.file_name().to_str()?; // <-- this works
if name.contains(".txt") {
Some(e)
} else {
None
}
});
for entry in valid_entries {
println!("This file matches: {:?}", entry);
let name_to_str = entry.file_name().to_str()?; // <-- this blows up
// ...
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
这些错误对我来说有点神秘:
use std::error::Error;
use walkdir::WalkDir;
fn main() -> Result<(), Box<dyn Error>> {
let valid_entries = WalkDir::new("/tmp")
.into_iter()
.flat_map(|e| e)
.flat_map(|e| {
let name = e.file_name().to_str()?; // <-- this works
if name.contains(".txt") {
Some(e)
} else {
None
}
});
for entry in valid_entries {
println!("This file matches: {:?}", entry);
let name_to_str = entry.file_name().to_str()?; // <-- this blows up
// ...
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
为什么?操作符在迭代时会爆炸valid_entries?
rod*_*igo 28
该?可用于检查和回报的任何类型的工具的Try特征(仍然不稳定)。其中唯一的实现std是Option<T>and Result<T, E>(加上一些Future与本讨论无关的相关实现)。这意味着您可以?在任何返回Result<T, E>or 的函数中使用该运算符Option<T>。
但是你不能混合n-match那些。也就是说,如果您的函数返回 a Result<T, E>,则不能?在 type 的值中使用 the Option<T>。或相反亦然。
你的第一个?作品的原因是因为你在一个flat_map()返回Option<String>并且一切顺利的里面。但是,第二个是在返回 a 的函数中,Result<(), Box<dyn Error>>因此您不能?与Option<String>.
解决方案只是以另一种方式处理None你的Option<String>:
match/if let Some(x)来单独处理错误。Result<String, Error>并使用?,例如 with .ok_or(std::io::ErrorKind::InvalidData)?;。impl From<&str> for Box<dyn Error>and do .ok_or("invalid file name")。Option::unwrap_or()或类似。unwrap()和恐慌如果None。好的,但是这个错误是什么意思?这个想法是,实际上你可以使用返回 a 的?an Option<T>,Result<T, E>只要你的Eimplements From<std::option::NoneError>。不幸的是,NoneError它仍然不稳定,因此您无法From<NoneError>使用稳定编译器在代码中实现。尽管如此,E您的代码中的 是Box<dyn Error>,并且只要NoneError实现Error,编译器就会很乐意进行装箱,但是......
error[E0277]: the trait bound `std::option::NoneError: std::error::Error` is not satisfied
Run Code Online (Sandbox Code Playgroud)