第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(())
}
这些错误让我难以理解:
error[E0277]: the trait bound `std::option::NoneError: std::error::Error` is not satisfied
--> src/main.rs:19:53
|
26 | let name_to_str = entry.file_name().to_str()?;
| ^ the trait `std::error::Error` is not implemented for `std::option::NoneError`
|
= note: required because of the requirements on the impl of `std::convert::From<std::option::NoneError>` for `std::boxed::Box<dyn std::error::Error>`
= note: required by `std::convert::From::from`
为什么?
运算符在迭代时会炸毁valid_entries
?
该?
可用于检查和回报的任何类型的工具的Try
特征(仍然不稳定)。其中的唯一实现std
是Option<T>
和Result<T, E>
(以及一些Future
与本讨论无关的相关暗示)。这意味着您可以?
在返回Result<T, E>
或的任何函数中使用运算符Option<T>
。
但是您不能对它们进行n匹配。也就是说,如果函数返回a Result<T, E>
,则不能使用?
in的type值Option<T>
。或相反亦然。
您的第一个?
作品是因为您在一个flat_map()
可以返回Option<String>
并且一切顺利的内部。但是,第二个函数在返回a的函数中,Result<(), Box<dyn Error>>
因此您不能将其?
与一起使用Option<String>
。
解决方案就是以另一种方式处理None
您Option<String>
的问题:
match
/if let Some(x)
分别处理错误。Result<String, Error>
和使用?
,例如与.ok_or(std::io::ErrorKind::InvalidData)?;
。impl From<&str> for Box<dyn Error>
和做.ok_or("invalid file name")
。Option::unwrap_or()
或相似的默认值。unwrap()
并惊慌None
。好的,但是这个错误是什么意思呢?这个想法是,实际上,只要您实现了,您就可以使用返回a的?
an 。不幸的是,它仍然也是不稳定的,因此您不能使用稳定的编译器在代码中实现。不过,您的代码中的是,只要实现,编译器很乐意进行装箱,但是...Option<T>
Result<T, E>
E
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句