1个不稳定版本

0.1.0 2020年4月7日

#2049 in 过程宏

MIT/Apache

6KB

Crates.io API reference

Versuch

Ok-wrapping函数的过程宏polyfill。

use versuch::try_fn;

#[try_fn]
fn word_count(path: &Path) -> io::Result<usize> {
    let mut res = 0;
    let file = fs::File::open(path)?;
    let mut reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line?;
        res += line.split_whitespace().count();
    }
    res
}

这是以下假设语法的polyfill

fn word_count(path: &Path) -> io::Result<usize> try {
    let mut res = 0;
    let file = fs::File::open(path)?;
    let mut reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line?;
        res += line.split_whitespace().count();
    }
    res
}

lib.rs:

Ok-wrapping函数的过程宏polyfill。

try块是Rust nightly版本中的一个功能,用于引入小于函数边界的操作符?。try块当前实现的一个显著特点是ok-wrapping。

let x: Option<i32> = try { 92 };
assert!(x.is_some());

也就是说,try { expr }会展开成,大致上,(|| Try::from_ok(expr))()

关键的是,您仍然需要使用?来传播错误,但不需要将最终值包装在Ok中。此外,如果最终值已经是Result类型,则需要额外添加一个?,使错误比没有ok-wrapping时更加明确。

try块的语法自然地推广到函数

fn word_count(path: &Path) -> io::Result<usize> try {
    let mut res = 0;
    let file = fs::File::open(path)?;
    let mut reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line?;
        res += line.split_whitespace().count();
    }
    res
}

不幸的是,即使使用过程宏,我们也不能完全实现这一点,但这个crate提供了一些相似的功能

use versuch::try_fn;

##[try_fn]
fn word_count(path: &Path) -> io::Result<usize> {
    let mut res = 0;
    let file = fs::File::open(path)?;
    let mut reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line?;
        res += line.split_whitespace().count();
    }
    res
}

这个crate深受https://crates.io/crates/fehler crate的启发。

免责声明:这个crate是一个过程宏,因此会显著增加依赖项数量和编译时间。它还会破坏IDE支持(对此表示歉意,@matklad)。

依赖关系

~1.5MB
~35K SLoC