1个不稳定版本
0.1.1 | 2022年7月29日 |
---|---|
0.1.1-alpha.1 |
|
0.1.0 |
|
15 在 #deref 中排名第 15
51 每月下载量
用于 ezno-parser
15KB
316 行
Deref
模式在 match
中,适用于稳定版Rust。现在您可以通过 Rc
、String
等
match_deref::match_deref!{...}
是一个过程宏,它允许您在稳定版Rust中使用deref模式。
例如
use std::rc::Rc;
enum Value {
Nil,
Cons(Rc<Value>, Rc<Value>),
Symbol(String),
}
use Value::*;
let v: &Value = todo!();
match_deref::match_deref!{
match v {
Nil => todo!(),
Cons(Deref @ Symbol(Deref @ "quote"), Deref @ Cons(x, Deref @ Nil)) => todo!(),
_ => todo!(),
}
}
但是,在我的crate中有一个问题:当编译器执行完备性检查时,所有带有 Deref @
的分支都会被忽略。因此,有时您需要在末尾添加 _ => unreachable!()
。
即,您的分支可能是完备的,但编译器无法进行检查。但是,如果您的分支不是完备的,编译器会错误地报告它们为完备。
(我决定不实现完整的完备性检查,因为我希望Rustc能够很快实现deref模式的真正原生支持,这样我的工作就不再需要了。但如果你想要实现具有完整完备性检查的类似宏,请继续,我甚至可以在这里链接到你的项目。)
该宏内部调用 Deref::deref
。请注意,Deref::deref
接受智能指针的引用并返回指向点的引用。因此,此代码将正常工作:match &Nil { Deref @ x => ... }
,但以下代码将不会:match Nil { Deref @ x => ... }
。
考虑以下代码
match_deref::match_deref!{
match v {
Symbol(Deref @ x) => some_code_here,
_ => other_code_here,
}
}
它将被转换为类似以下的形式
match v {
Symbol(a0) if (if let x = Deref::deref(a0) { true } else { false }) => if let x = Deref::deref(a0) {
some_code_here
} else {
panic!()
},
_ => other_code_here,
}
我的宏是卫生的,也就是说,即使你使用名为 a0
的变量,一切也会正常工作
您无需在 SourceHut 上注册即可创建错误报告。
如果您认为此软件不是必需的,或者现有软件已经涵盖了其功能,请告诉我,我不会介意。
依赖项
~1.5MB
~36K SLoC