gpt4 book ai didi

error-handling - Rust:从 stdin 读取和映射行并处理不同的错误类型

转载 作者:行者123 更新时间:2023-12-03 07:41:29 25 4
gpt4 key购买 nike

我正在学习 Rust 并试图用它解决一些基本的算法问题。在许多情况下,我想从 stdin 读取行,对每一行执行一些转换并返回结果项的向量。我这样做的一种方法是这样的:

    // Fully working Rust code
let my_values: Vec<u32> = stdin
.lock()
.lines()
.filter_map(Result::ok)
.map(|line| line.parse::<u32>())
.filter_map(Result::ok)
.map(|x|x*2) // For example
.collect();

这有效,但当然会默默地忽略可能发生的任何错误。现在我想做的事情是这样的:

    // Pseudo-ish code
let my_values: Result<Vec<u32>, X> = stdin
.lock()
.lines() // Can cause std::io::Error
.map(|line| line.parse::<u32>()) // Can cause std::num::ParseIntError
.map(|x| x*2)
.collect();

其中 X 是某种错误类型,我之后可以匹配。最好我想一次在一行上执行整个操作,并在将字符串数据解析为 int 后立即丢弃它。

我想我需要创建某种 Enum 类型来保存各种可能的错误,可能是这样的:

#[derive(Debug)]
enum InputError {
Io(std::io::Error),
Parse(std::num::ParseIntError),
}

但是,我不太明白如何将所有内容放在一起以使其干净并避免必须在任何地方显式匹配和强制转换。另外,是否有某种方法可以自动创建这些枚举错误类型,还是每次执行此操作时都必须明确枚举它们?

最佳答案

你在正确的轨道上。
我的方法是使用您定义的枚举,
然后添加 From 的实现对于您感兴趣的错误类型。
这将允许您使用 ?操作符以获取您想要的行为类型。

#[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)
}
}


然后您可以将实际转换实现为
let my_values: Vec<_> = stdin
.lock()
.lines()
.map(|line| -> Result<u32,MyError> { Ok(line?.parse::<u32>()?*2) } )
.collect();

这将为每个输入提供一个条目,例如: {Ok(x), Err(MyError(x)), Ok(x)} .
或者你可以这样做:
let my_values: Result<Vec<_>,MyError> = stdin
.lock()
.lines()
.map(|line| -> Result<u32,MyError> { Ok(line?.parse::<u32>()?*2) } )
.collect();

哪个会给你 Err(MyError(...))Ok([1,2,3])
请注意,您可以通过使用像 snafu 这样的错误处理箱来进一步减少一些错误样板文件。 ,但在这种情况下,它并不过分。

关于error-handling - Rust:从 stdin 读取和映射行并处理不同的错误类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59187274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com