例如:
## Here is the table
commune container house aegypti albopictus
yde4 c1 h1 6 6
yde2 c2 h2 2 3
yde7 c3 h3 1 0
yde7 c3 h4 1 1
yde7 c5 h5 8 0
yde7 c6 h6 0 0
yde4 c7 h7 4 1
yde7 c8 h8 14 9
yde3 c9 h9 0 1
yde3 c10 h10 6 2
## here is how it should display
aegypti albopictus
com house_pros c_found Pos_container In Pos_container In
yde2 1 1 1 100 1 100
yde3 2 2 1 50 2 100
yde4 2 2 2 100 2 100
yde7 4 5 4 100 2 40
Total 9 10 8 88 7 70
什么是允许extern crate failure;
use std::fs::File;
fn f() -> std::result::Result<(), failure::Error>
let _ = File::open("test")?;
"123".parse::<u32>()?;
Ok(())
}
能够表示failure::Error
,解析错误和任何其他自定义错误类型的技术?重新创建此功能的最低实现是什么?
答案 0 :(得分:2)
这里有两种机制。
第一种机制是问号运算符returns Err(From::from(e))
when it encounters an Err(e)
。如果函数返回类型为Result<T, E>
,则这允许我们返回F
实现E
的任何错误类型From<F>
。
从failure::Error
类型的文档中,我们可以看到有一个generic From
implementation for all types implementing the failure::Fail
trait和一个generic implementation of Fail
for all types implementing std::error::Error
(只要它们也是Send + Sync + 'static
) 。结合起来,这使我们可以返回实现failure::Fail
特征或std::error::Error
特征的任何类型。标准库中的所有错误类型都实现Error
特征,包括std::io::Error
和std::num::ParseIntError
。
这已经解释了为什么编译代码,但是没有解释转换在内部如何工作。这是由起作用的第二种机制-特征对象解释的。 Error
包装箱中的failure
类型的(略作编辑的)定义是这样的:
struct Error {
imp: ErrorImpl,
}
struct ErrorImpl {
inner: Box<Inner<dyn Fail>>,
}
struct Inner<F: ?Sized + Fail> {
backtrace: Backtrace,
failure: F,
}
Inner
类型将错误存储为使用动态分派进行方法调用的特征对象。
答案 1 :(得分:1)
failure::Error::from_boxed_compat
构造函数用于将任何错误转换为failure::Error
。
pub fn from_boxed_compat(err: Box<dyn StdError + Sync + Send + 'static>) -> Error
此函数采用任何暗示Error的结构作为输入,并构造一个failure::Error
https://docs.rs/failure/0.1.5/failure/struct.Error.html#impl
failure::Error
在其中包含一个堆存储的特征对象,该对象可以存储实现Error对象的结构。
struct ErrorImpl {
inner: Box<Inner<Fail>>,
}
此外,看来Fail trait
已实现许多错误。 ?
运算符将添加一个into
方法,该方法会将错误转换为failure::Error