6 个版本
0.2.0 | 2023 年 11 月 29 日 |
---|---|
0.1.5 | 2023 年 7 月 4 日 |
0.1.3 | 2023 年 6 月 29 日 |
#735 在 Rust 模式 中
19KB
487 行
列表推导
Rust 中的类似 Haskell 的列表推导宏
语法
ListComprehensionExp:
comp![ Exp , Qual1 , . . . , Qualn ] (list comprehension, n ≥ 1 )
| comp![ Exp ; Qual1 , . . . , Qualn ] (list comprehension, n ≥ 1 )
| comp![ Exp => Qual1 , . . . , Qualn ] (list comprehension, n ≥ 1 )
| lazy_comp![ Exp , Qual1 , . . . , Qualn ] (lazy list comprehension, n ≥ 1 )
| lazy_comp![ Exp ; Qual1 , . . . , Qualn ] (lazy list comprehension, n ≥ 1 )
| lazy_comp![ Exp => Qual1 , . . . , Qualn ] (lazy list comprehension, n ≥ 1 )
Qual:
Ident <- Exp (generator)
| (for)? Pattern in Exp (generator[2])
| let Decl (local declaration)
| let DeclWithElse (local declaration)
| let (mut)? Decls (local declaration[1])
| Exp(bool) (boolean guard)
Decls:
{ Decl1 ; . . . ; Decln } (n ≥ 0)
Decl:
(mut)? Ident ( : Type )? = Exp
| Pat = Exp ( , else { ... } )?
DeclWithElse:
Pat = Exp else { ... }
[1] if `mut` is used, then all declarations will be added with `mut` unless pattern matching is used
[2] Since parsing the `Pattern in Exp` syntax and the `Exp` (boolean guard) syntax can be ambiguous,
you can now force the `Pattern in Exp` syntax by prefixing the `Pattern` with `for`
示例
fn main() {
// example 1
let arr1: Vec<i32> = comp![n; n in [0, 1, 2, 3], n != 3];
assert_eq!(arr1, [0, 1, 2]);
// expand the macro:
let arr1: Vec<i32> = {
let mut res = Vec::new();
for n in [0, 1, 2, 3] {
if !(n != 3) {
continue;
}
res.push(n);
}
res
};
// ----------------------------------------------------------------------------------------------------
// example 2
let a = [0, 1, 2];
let arr2: Vec<(i32, i32)> = comp![
(n, m)
, n in a
, m in [0, 1, 2]
, n != 2
, m != 2
];
assert_eq!(arr2, [(0, 0), (0, 1), (1, 0), (1, 1)]);
// expand the macro:
let arr2: Vec<(i32, i32)> = {
let mut res = Vec::new();
for n in a {
for m in [0, 1, 2] {
if !(n != 2) {
continue;
}
if !(m != 2) {
continue;
}
res.push((n, m));
}
}
res
};
// ----------------------------------------------------------------------------------------------------
// example 3
let arr3 = lazy_comp![
{ println!("{i}"); i }
, i in 0..3
];
for _ in arr3 {
println!("------")
}
// console output:
// 0
// ------
// 1
// ------
// 2
// ------
// You can see more examples in tests/test_comp.rs
}
更新
- v0.2.0
- 添加了支持懒计算的
lazy_comp
宏,其语法与comp!
相同。
- 添加了支持懒计算的
- v0.1.5
- 支持原始的
let else
语法,但不能在let { ... }
语法中使用。 - 现在您可以通过在
Pattern in Exp
语法前加for
来强制使用Pattern
(详细信息请参阅语法)。
- 支持原始的
- v0.1.4
- 允许在局部声明中使用
pattern matching
和不同的let else
。 - 进行了一些优化。
- 纠正了 README 中的少量错误。
- 允许在局部声明中使用
依赖项
~25KB