创建新错误时重复使用现有错误的描述
Reuse the description of an existing Error when creating a new Error
我在 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 })
}
}
本质上,我想获取字节顺序库返回的错误的错误描述,并使用它来创建错误描述,我将传回给我的库的用户。这失败了 packets.rs:166:58: 166:63 error:
错误 does not live long enough
,我明白为什么。
byteorder 库通过在 byteorder::Error::Io
构造函数中包装 std::io::Result
解决了这个问题。但是,我不想走这条路,因为我必须定义自己的错误类型来包装 std::io::Error
或 byteorder::Error
。在我看来,我的用户不应该知道或关心我使用字节顺序库,它不应该成为我界面的一部分。
我是 Rust 新手,还不知道语言和设计的惯用语和最佳实践。我有什么选择来处理这个问题?
我无法测试您的代码,所以无法确定。 ref 关键字还不够吗?
Err(byteorder::Error::Io(ref error)) => Err(error),
你的问题实际上是 io::Error::new()
's second parameter is &'static str
, while byteorder::Error::description()
returns a &'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())
)),
但是,您应该认真考虑制作一个自定义包装器错误类型来封装所有 "downstream" 错误。使用正确编写的 FromError
实例,您应该能够编写类似
的内容
try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
而不是你的整场比赛。当您的程序增长并且出现更多 "downstream" 错误源时,自定义错误包装器也会帮助您 - 您可以添加新的枚举变体 and/or FromError
实现来支持这些新错误。
我在 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 })
}
}
本质上,我想获取字节顺序库返回的错误的错误描述,并使用它来创建错误描述,我将传回给我的库的用户。这失败了 packets.rs:166:58: 166:63 error:
错误 does not live long enough
,我明白为什么。
byteorder 库通过在 byteorder::Error::Io
构造函数中包装 std::io::Result
解决了这个问题。但是,我不想走这条路,因为我必须定义自己的错误类型来包装 std::io::Error
或 byteorder::Error
。在我看来,我的用户不应该知道或关心我使用字节顺序库,它不应该成为我界面的一部分。
我是 Rust 新手,还不知道语言和设计的惯用语和最佳实践。我有什么选择来处理这个问题?
我无法测试您的代码,所以无法确定。 ref 关键字还不够吗?
Err(byteorder::Error::Io(ref error)) => Err(error),
你的问题实际上是 io::Error::new()
's second parameter is &'static str
, while byteorder::Error::description()
returns a &'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())
)),
但是,您应该认真考虑制作一个自定义包装器错误类型来封装所有 "downstream" 错误。使用正确编写的 FromError
实例,您应该能够编写类似
try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
而不是你的整场比赛。当您的程序增长并且出现更多 "downstream" 错误源时,自定义错误包装器也会帮助您 - 您可以添加新的枚举变体 and/or FromError
实现来支持这些新错误。