#try #unwrap #let #else

internal

inner! 宏可以递归到枚举变体中。它比 try!() 和 unwrap() 更灵活,并且也可以与您的枚举一起使用!

1 个不稳定版本

使用旧的 Rust 2015

0.1.1 2016 年 2 月 5 日
0.1.0 2016 年 2 月 2 日

1914Rust 模式

Download history 2640/week @ 2024-03-13 2443/week @ 2024-03-20 1875/week @ 2024-03-27 3624/week @ 2024-04-03 1914/week @ 2024-04-10 2533/week @ 2024-04-17 3474/week @ 2024-04-24 1383/week @ 2024-05-01 1379/week @ 2024-05-08 2187/week @ 2024-05-15 1415/week @ 2024-05-22 2371/week @ 2024-05-29 2401/week @ 2024-06-05 1705/week @ 2024-06-12 1445/week @ 2024-06-19 712/week @ 2024-06-26

6,734 每月下载量
用于 2 crates

Apache-2.0/MIT

15KB
233

inner! 宏使得递归到枚举变体更加方便。而 some!ok! 宏则将枚举转换为 OptionResult

Crates.io

API 文档

有用的 unwrap

最简单的情况几乎就像 unwrap 一样

let x = Some(1);
let y: Result<_, ()> = Ok(2);
assert_eq!(inner!(x), 1);
assert_eq!(inner!(y), 2);

...但如果你在 NoneErr 值上使用它

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 子句来计算默认值,或使用流程控制(例如 breakcontinuereturn)。

想访问 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

它也适用于您的枚举

它不仅适用于 OptionResult。只需添加一个 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 子句则提供了最大的灵活性,可以返回 ErrOk

另一种选择是为你的枚举实现此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

无运行时依赖