4个版本
0.0.1-release | 2019年2月12日 |
---|---|
0.0.1-preview | 2019年2月11日 |
#1472 在 Rust模式
30KB
535 行
Rust中的Linq
在Rust中使用声明性宏创建的语言集成查询
- 灵感来源于.NET中的LINQ。
- LINQ是什么
此项目正在开发中! API可能会发生更改。
快速入门
这是一个示例
use linq::linq;
use linq::iter::Enumerable;
fn try_linq_methods() {
let x = 1..100;
let mut y: Vec<i32> = x.clone().filter(|p| p <= &5).collect();
y.sort_by_key(|t| -t);
let y: Vec<i32> = y.into_iter().map(|t| t * 2).collect();
let e: Vec<i32> = x
.clone()
.where_by(|p| p <= &5)
.order_by(|p| -p)
.select(|p| p * 2)
.collect();
assert_eq!(e, y);
}
fn try_linq_expr() {
let x = 1..100;
let mut y: Vec<i32> = x.clone().filter(|p| p <= &5).collect();
y.sort_by_key(|t| -t);
let y: Vec<i32> = y.into_iter().map(|t| t * 2).collect();
let e: Vec<i32> =
linq!(from p in x.clone(), where p <= &5, orderby -p, select p * 2).collect();
assert_eq!(e, y);
}
如果你熟悉C#中的LINQ,你会发现这很容易使用。
用法
这两个导入是必需的
use linq::linq; // for `linq!` macro
use linq::iter::Enumerable; // for LINQ methods and `linq!` macro
方法
特质linq::iter::Enumerable
支持在Iterator
上使用LINQ方法。以下是一些对应关系。
- 普通项表示它们是std中
Iterator
的内置方法。 - 加粗项表示它们在此项目中实现。您可以在模块
linq::iter
中找到它们(但它们是私有的,因此您不能导入它们)。 - 斜体项表示它们不在路线图中。欢迎您的建议。
- 更多示例请参见这里。
- where => where_by => filter
- select => map
- select_many => select_many_single, select_many
- skip
- skip_while
- take
- take_while
- join
- group_join
- concat => chain
- order_by
- order_by_descending
- then_by
- then_by_descending
- reverse => rev
- group_by
- distinct
- union
- intersect
- except
- first => next
- single
- element_at => nth
- all
- any
- contains
- count
- sum
- product
- min
- max
- average
- aggregate => fold
表达式
查询表达式以from
子句开始,以select
子句结束。使用,
分隔每个子句。
linq!(from x in coll, select x)
目前支持以下关键字
- from
- from (
select_many_single
) - zfrom (
select_many
)
- from (
- in
- select
- where
- orderby
- descending
- group_by
- 更多...
来自
from <id> in <iter expr>,
此外,您还可以列出集合中每个集合的元素(注意:对于此类型,您无法访问select
子句中第一个from
子句中的值)
let x = 1..5;
let y = vec![0, 0, 1, 0, 1, 2, 0, 1, 2, 3];
let e: Vec<i32> = linq!(from p in x.clone(), from t in 0..p, select t).collect();
assert_eq!(e, y);
如果您想压缩或列出两个集合的值对,请使用zfrom
作为第二个from
let x = 1..5;
let y = vec![
(1, 0),
(2, 0),
(2, 1),
(3, 0),
(3, 1),
(3, 2),
(4, 0),
(4, 1),
(4, 2),
(4, 3),
];
let e: Vec<_> = linq!(from p in x.clone(), zfrom t in 0..p, select (p,t)).collect();
assert_eq!(e, y);
zfrom
中的表达式接收第一个from
中克隆的值,并将两个集合中的元素克隆用于select
子句。
位置
where <expr>,
在单个来源查询中,您可以使用where
子句。表达式将接收在from
子句中命名的变量id
。表达式需要返回一个布尔值。
Orderby
orderby <expr>,
orderby <expr>, descending,
在单个来源查询中,您可以使用orderby
子句。此查询将收集迭代器,并按表达式排序,然后返回新的迭代器。
开发
我们需要更多的单元测试样本。如果您有任何想法,请创建问题告诉我们。
由于表达式过程宏不稳定,我仅通过声明性宏创建宏。
$ cargo test