1 个不稳定版本
使用旧的 Rust 2015
0.1.1 | 2016 年 2 月 5 日 |
---|---|
0.1.0 |
|
1914 在 Rust 模式 中
6,734 每月下载量
用于 2 crates
15KB
233 行
inner!
宏使得递归到枚举变体更加方便。而 some!
和 ok!
宏则将枚举转换为 Option
或 Result
。
有用的 unwrap
最简单的情况几乎就像 unwrap 一样
let x = Some(1);
let y: Result<_, ()> = Ok(2);
assert_eq!(inner!(x), 1);
assert_eq!(inner!(y), 2);
...但如果你在 None
或 Err
值上使用它
let z = None;
let y = inner!(z);
...它将引发 panic,错误信息将指向比 libcore 内的某个行号更有帮助的位置
thread "test" panicked at "Unexpected value found inside "z"", src/lib.rs:23
错误处理
如果 panic 不是选项 - 而且通常不是 - 只需添加一个 else
子句
let x: Result<String, i32> = Err(7);
let y = inner!(x, else { return });
// Since x is an Err, we'll never get here.
println!("The string length is: {}", y.len());
您可以使用 else 子句来计算默认值,或使用流程控制(例如 break
,continue
或 return
)。
想访问 else
子句中的 Err
值?没问题,只需在 else
后面添加一个 |variable|
,就像这样
let x: Result<String, i32> = Err(7);
let y = inner!(x, else |e| {
assert_eq!(e, 7);
(e + 2).to_string()
});
assert_eq!(&y, "9");
注意:这并不会将您的 else 子句转换为闭包,因此您仍然可以像以前一样使用(例如)return
。
它也适用于您的枚举
它不仅适用于 Option
和 Result
。只需添加一个 if
子句
enum Fruit {
Apple(i32),
Orange(i16),
}
let z = Fruit::Apple(15);
let y = inner!(z, if Fruit::Apple, else {
println!("I wanted an apple and I didn't get one!");
0
});
assert_eq!(y, 15);
您可以选择跳过 else
子句,以便在枚举不是预期变体时引发 panic。
请注意,在这种情况下,整个项目(而不是 Err
内的内容)都传递给了 else
子句
#[derive(Eq, PartialEq, Debug)]
enum Fruit {
Apple(i32),
Orange(i16),
}
let z = Fruit::Orange(15);
inner!(z, if Fruit::Apple, else |e| {
assert_eq!(e, Fruit::Orange(15));
return;
});
您还可以使用 Some
宏将您的枚举转换为 Option
assert_eq!(some!(Fruit::Apple(15), if Fruit::Apple), Some(15));
assert_eq!(some!(Fruit::Orange(5), if Fruit::Apple), None);
assert_eq!(some!(Fruit::Orange(5), if Fruit::Apple, else |e| {Some(e + 2)}), Some(7));
或者使用 ok!()
宏将其转换为 Result
assert_eq!(ok!(Fruit::Apple(15), if Fruit::Apple), Ok(15));
assert_eq!(ok!(Fruit::Orange(5), if Fruit::Apple), Err(Fruit::Orange(5)));
assert_eq!(ok!(Fruit::Orange(5), if Fruit::Apple, or |e| {e + 70}), Err(75));
assert_eq!(ok!(Fruit::Orange(5), if Fruit::Apple, else {Err(75)}), Err(75));
请注意,ok!()
宏有一个可选的 or
子句,该子句将表达式封装在 Err
中,而 else
子句则提供了最大的灵活性,可以返回 Err
或 Ok
。
另一种选择是为你的枚举实现此crate的 IntoResult
trait。这样,你就不必编写 if
子句来指定你想要下降到的枚举变体,你可以选择多个枚举变体作为 Ok
enum Fruit {
Apple(i32),
Orange(i16),
Rotten,
}
impl IntoResult<i32, ()> for Fruit {
fn into_result(self) -> Result<i32, ()> {
match self {
Fruit::Apple(i) => Ok(i),
Fruit::Orange(i) => Ok(i as i32),
Fruit::Rotten => Err(()),
}
}
}
assert_eq!(9, inner!(Fruit::Apple(9)));
许可证
Apache2.0/MIT