Error handling Rust:从stdin读取和映射行,并处理不同的错误类型
我正在学习Rust并试图用它解决一些基本的算法问题。在许多情况下,我希望从stdin中读取行,对每行执行一些转换,并返回结果项的向量。我这样做的一种方式是:Error handling Rust:从stdin读取和映射行,并处理不同的错误类型,error-handling,rust,idioms,Error Handling,Rust,Idioms,我正在学习Rust并试图用它解决一些基本的算法问题。在许多情况下,我希望从stdin中读取行,对每行执行一些转换,并返回结果项的向量。我这样做的一种方式是: //完全工作的防锈代码 让我的_值为:Vec=stdin .lock() .行() .filter_映射(结果::ok) .map(| line | line.parse::()) .filter_映射(结果::ok) .map(|x | x*2)//例如 .收集(); 这是可行的,但当然会忽略可能发生的任何错误。现在我想做的事情大致如下
//完全工作的防锈代码
让我的_值为:Vec=stdin
.lock()
.行()
.filter_映射(结果::ok)
.map(| line | line.parse::())
.filter_映射(结果::ok)
.map(|x | x*2)//例如
.收集();
这是可行的,但当然会忽略可能发生的任何错误。现在我想做的事情大致如下:
//伪ish代码
让我的值:Result=stdin
.lock()
.lines()//可能导致std::io::错误
.map(| line | line.parse::())//可以导致std::num::parseinteror
.map(|x | x*2)
.收集();
其中X是某种类型的错误类型,我可以在以后进行匹配。最好是一次在一行上执行整个操作,并在字符串数据被解析为int后立即丢弃它
我想我需要创建某种枚举类型来保存各种可能的错误,可能如下所示:
#[派生(调试)]
枚举输入程序{
Io(标准::Io::错误),
解析(std::num::parseinteror),
}
然而,我不太明白如何把所有的东西放在一起,使它干净,避免显式地匹配和到处施放。另外,是否有某种方法可以自动创建这些枚举错误类型,或者每次我都必须明确地枚举它们?您的思路是正确的。
我的方法是使用您定义的枚举,
然后为您感兴趣的错误类型添加来自的实现。
这将允许您在地图上使用?
操作符来获得所需的行为
#[derive(Debug)]
enum MyError {
IOError(std::io::Error),
ParseIntError(std::num::ParseIntError),
}
impl From<std::io::Error> for MyError {
fn from(e:std::io::Error) -> MyError {
return MyError::IOError(e)
}
}
impl From<std::num::ParseIntError> for MyError {
fn from(e:std::num::ParseIntError) -> MyError {
return MyError::ParseIntError(e)
}
}
这将为您提供Err(MyError(…)
或Ok([1,2,3])
请注意,您可以通过使用错误处理板条箱(如snafu
)来进一步减少一些错误样板,但在这种情况下,这并不太多。作为替代方法,您可以通过将my_值
声明为Result
类型,作为?
自动框错误来避免从实现中写入。另请参见:@asky-Yep,这也会起作用。但我认为,如果您想在以后进行更高级的错误处理,那么返回原始错误的具体类型可能会很棘手。(这可能是为什么有这么多错误处理板条箱的一个重要原因)。
let my_values: Vec<_> = stdin
.lock()
.lines()
.map(|line| -> Result<u32,MyError> { Ok(line?.parse::<u32>()?*2) } )
.collect();
let my_values: Result<Vec<_>,MyError> = stdin
.lock()
.lines()
.map(|line| -> Result<u32,MyError> { Ok(line?.parse::<u32>()?*2) } )
.collect();