我在Rust中有以下代码,它不能编译,但显示了我想要做的事情。
pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> {
use self::byteorder::{BigEndian, ReadBytesExt};
use self::core::error::Error;
match cursor.read_u16::<BigEndian>() {
Err(byteorder::Error::Io(error)) => Err(error),
Err(error) =>
Err(io::Error::new(io::ErrorKind::Other, error.description(),
None)),
Ok(value) => Ok(Ack { block_number: value })
}
}
本质上,我想获取byteorder库返回的错误的错误描述,并使用它来创建错误的描述,我将传回给我的库用户。此操作因packets.rs:166:58: 166:63 error:
错误does not live long enough
而失败,我明白了原因。
byteorder库通过在std::io::Result
构造函数中包装byteorder::Error::Io
来解决此问题。但是,我不想采用这种方式,因为我必须定义包含std::io::Error
或byteorder::Error
的错误类型。在我看来,我的用户不应该知道或不关心我使用字节顺序库,它不应该成为我的界面的一部分。
我是Rust新手,还不知道语言和设计的习语和最佳实践。我可以选择处理这个问题吗?
答案 0 :(得分:1)
您的问题实际上是io::Error::new()
的第二个参数是&'static str
,而byteorder::Error::description()
返回&'a str
,其中'a
是有效期错误对象本身的值小于'static
。因此,您无法将其用于io::Error
的说明。
最简单的解决方法是将byteorder::Error
说明移至detail
的{{1}}字段:
io::Error
但是,您应该认真考虑制作一个自定义包装器错误类型,它封装了所有&#34;下游&#34;错误。使用正确编写的FromError
实例,您应该能够编写类似
Err(error) =>
Err(io::Error::new(
io::ErrorKind::Other,
"byteorder error",
Some(error.description().to_string())
)),
而不是你的整场比赛。自定义错误包装器也可以帮助您在程序增长时使用更多&#34;下游&#34;出现错误来源 - 您可以添加新的枚举变体和/或try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
实现来支持这些新错误。
答案 1 :(得分:0)
我无法测试您的代码,所以我无法确定。 ref关键字不够用吗?
Err(byteorder::Error::Io(ref error)) => Err(error),