Error handling 创建新错误时重用现有错误的描述
我在Rust中有以下代码,它不编译,但显示了我想做的事情的意图Error handling 创建新错误时重用现有错误的描述,error-handling,rust,Error Handling,Rust,我在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:
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 })
}
}
发布fn解析(游标:&mut io::游标)->io::结果{
使用self::byteorder::{BigEndian,ReadBytesExt};
使用self::core::error::error;
匹配光标。读取\ u16::(){
Err(字节顺序::错误::Io(错误))=>Err(错误),
Err(error)=>
Err(io::Error::new(io::ErrorKind::Other,Error.description(),
无),,
Ok(值)=>Ok(确认{块编号:值})
}
}
本质上,我希望获取字节顺序库返回的错误的错误描述,并使用它创建一个错误的描述,我将传递回我的库的用户。这在数据包中失败。rs:166:58:166:63错误:
错误寿命不够长,我理解原因
字节顺序库通过在byteorder::Error::io
构造函数中包装std::io::Result
来解决此问题。但是,我不想采用这种方法,因为我必须定义自己的错误类型,该类型包含std::io::error
或byteorder::error
。在我看来,我的用户不应该知道或关心我使用字节顺序库,它也不应该是我界面的一部分
我是个新手,还不知道语言和设计的习惯用法和最佳实践。处理这个问题我有什么选择?我无法测试您的代码,所以我不能确定。ref关键字还不够吗
Err(byteorder::Error::Io(ref error)) => Err(error),
您的问题实际上在于,第二个参数是&'static str
,而返回一个&'a str
,其中'a
是错误对象本身的生存期,它小于'static
。因此,您不能将其用于io::Error
的描述
最简单的修复方法是将byteorder::Error
描述移动到io::Error
的detail
字段:
Err(error) =>
Err(io::Error::new(
io::ErrorKind::Other,
"byteorder error",
Some(error.description().to_string())
)),
不过,您应该认真考虑编写一个封装所有“下游”错误的自定义包装错误类型。使用正确编写的实例,您应该能够编写如下内容
try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
试试看!(光标。读_u16::)
.map(| value | Ack{block_number:value}))
而不是你的整个比赛。自定义错误包装器也将在您的程序增长和出现更多“下游”错误源时为您提供帮助-您可以添加新的枚举变量和/或FromError
实现以支持这些新错误。不幸的是,我要到明天才能再次回到这一点,但我将尝试并报告。谢谢。我最终实现了自定义错误包装器,因为这似乎是最惯用的方法。我还没试过,但是试一下吧!。。。地图方法很简洁。