error-handling - 为什么?操作员报告错误“特征绑定NoneError:不满足错误”?
问题描述
第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>
and Result<T, E>
(加上一些Future
与本讨论无关的相关 impls)。这意味着您可以?
在任何返回Result<T, E>
或的函数中使用运算符Option<T>
。
但是你不能混合搭配那些。也就是说,如果您的函数返回 a ,则您Result<T, E>
不能?
在 type 的值中使用Option<T>
。或相反亦然。
你第一次?
工作的原因是因为你在一个flat_map()
返回Option<String>
并且一切顺利的内部。但是,第二个是在返回 a 的函数中,Result<(), Box<dyn Error>>
因此您不能与 a?
一起使用Option<String>
。
解决方案只是以另一种方式处理None
您的问题:Option<String>
- 做
match
/if let Some(x)
来分别处理错误。 - 转换为 a
Result<String, Error>
并使用?
,例如 with.ok_or(std::io::ErrorKind::InvalidData)?;
。 - 类似于 2,但利用
impl From<&str> for Box<dyn Error>
and do.ok_or("invalid file name")
。 - 给出一个默认值,有
Option::unwrap_or()
或类似。 - 做
unwrap()
和恐慌如果None
。
好的,但是这个错误是什么意思?这个想法是,实际上你可以使用?
返回Option<T>
a 的 a Result<T, E>
,只要你的E
implements 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
推荐阅读
- google-cloud-platform - 使用 GCP 网络端点组进行容器原生负载平衡的不健康后端
- python - Python Tkinter - 如何将一个类中的小部件放到另一个类的窗口中
- java - 如何使用具有特定坐标的 javafx 绘制路径?
- xml - 使用 XSLT 1.0 模拟数据透视表
- string - lua string.find 无法识别子字符串
- javascript - 车把每个句子不循环
- c# - Fresh dotnet new mvc 项目@Linux - 无法验证 HTTPS 连接
- gtk - 在windows上设置Gtk开发
- bit-manipulation - 位操作:在一组位的最左角添加位
- javascript - 将 CSV 从实时 URL 解析为 HTML 表