1个不稳定版本
0.1.0 | 2020年4月7日 |
---|
#2049 in 过程宏
6KB
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