我正在尝试解析一些用户输入,输入存储在一个结构中,其中有很多选项/结果(以处理用户输入之前未初始化的数据),当用户提交它时,它需要进入一个所有值都已知的结构。
我希望能够获得包含任何错误的向量,以便我可以向用户提供有关输入的所有错误(而不仅仅是第一个错误)的反馈。但是,我找不到一个好的方法来做到这一点。
struct Test {
x: i32,
y: String,
}
#[derive(Debug)]
enum Errors {
OneIsNone,
TwoIsNone,
}
我目前的做法是:
fn main() -> Result<Test, Vec<Errors>> {
let option1 = Some(5);
let option2 = None;
let mut errors = Vec::new();
let x: i32;
match option1 {
Some(value) => x = value,
None => errors.push(Errors::OneIsNone),
};
let y: String;
match option2 {
Some(value) => y = value,
None => errors.push(Errors::TwoIsNone),
}
if errors.len() != 0 {
return Err(errors)
}
Ok(
Test {
x,
y
}
)
}
这不起作用,因为如果代码到达
Ok
块,编译器无法告诉 x 和 y 必须初始化。
在这种情况下,我可以直接展开匹配两个结果,但对于具有大量字段的结构来说,这种方法将变得极其笨拙。
基本上我想要一种方法来获取大量结果并将它们解析为一个结构(如果它们都给出
Ok()
)或返回包含所有错误的向量,否则即如何在中实现
unwrap_or_errors
fn main() -> Result<Test, Vec<Errors>> {
let option1 = Some(5);
let option2 = None;
let mut errors = Vec::new();
let x = match option1 {
Some(val) => Ok(val),
None => Err(Errors::OneIsNone),
};
let y = match option2 {
Some(val) => Ok(val),
None => Err(Errors::TwoIsNone),
};
if errors.len() != 0 {
return Err(errors)
}
Test::unwrap_or_errors(x, y)?
}
您可以对成功案例使用元组模式匹配,对失败案例使用迭代器扁平化:
struct Test {
x: i32,
y: String,
}
impl Test {
fn unwrap_or_errors(
x: Result<i32, Errors>,
y: Result<String, Errors>,
) -> Result<Self, Vec<Errors>> {
match (x, y) {
(Ok(x), Ok(y)) => Ok(Self { x, y }),
(x, y) => Err([x.err(), y.err()]
.into_iter()
.flatten()
.collect()),
}
}
}
#[derive(Debug)]
enum Errors {
OneIsNone,
TwoIsNone,
}
fn new() -> Result<Test, Vec<Errors>> {
let option1 = Some(5);
let option2 = None;
let x = match option1 {
Some(val) => Ok(val),
None => Err(Errors::OneIsNone),
};
let y = match option2 {
Some(val) => Ok(val),
None => Err(Errors::TwoIsNone),
};
Test::unwrap_or_errors(x, y)
}