Skip to content

Commit 71287f0

Browse files
完成readme.md
1 parent 00e87cf commit 71287f0

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed

README.md

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
# better_comprehension
2+
3+
在rust中的集合推导式和迭代器推导式。提供更好的Rust使用体验。
4+
Collection comprehension and Iterator comprehension in Rust. And it provides a better experience in Rust.
5+
6+
# Usage
7+
语法源自[python推导式](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions)
8+
本库为Rust标准库中的所有集合类型提供宏,以及基于引用的迭代器。
9+
The syntax is derived from [Python's comprehension](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions).
10+
This library provides macros for all collection types in the Rust standard library and an Iterator based on references.
11+
12+
简单示例
13+
simple example
14+
```rust
15+
let vec_1 = vec!["AB".to_string(), "CD".to_string()];
16+
let vec: Vec<String> = vector![x.clone() for x in vec_1];
17+
assert_eq!(vec, vec!["AB".to_string(), "CD".to_string()]);
18+
```
19+
20+
你也可以在推导式中使用模式
21+
You can also use patterns in it
22+
```rust
23+
struct Person {
24+
name: String,
25+
age: i32,
26+
}
27+
let people = [Person { name: "Joe".to_string(), age: 20 },
28+
Person { name: "Bob".to_string(), age: 25 }];
29+
let vec_deque = vec_deque![name.clone() for Person { name, .. } in people];
30+
assert_eq!(vec_deque, VecDeque::from(["Joe".to_string(), "Bob".to_string()]));
31+
```
32+
33+
过滤值
34+
filtering values
35+
```rust
36+
let linked_list = linked_list![ i*2 for i in 1..=3 if i != 2 ];
37+
assert_eq!(linked_list, LinkedList::from([2, 6]));
38+
```
39+
40+
根据条件返回不同的值
41+
return different values based on conditions
42+
```rust
43+
let b_tree_set = b_tree_set!{
44+
i if i-1 == 0 else i+10
45+
for i in 1..=3 if i != 2
46+
};
47+
assert_eq!(b_tree_set, BTreeSet::from([1, 13]));
48+
```
49+
50+
嵌套推导式
51+
nested comprehension
52+
```rust
53+
let binary_heap = binary_heap![
54+
i if (i-1 == 0 || j -2 == 0) else i+10
55+
for i in 1..=3 if i != 2
56+
for j in 1..=3 if j+i != 4];
57+
assert_eq!(binary_heap.into_sorted_vec(), vec![1, 1, 3, 13]);
58+
```
59+
60+
和python的推导式一样, 本库的for循环是从上到下读取的.
61+
the reading order of the for loop in this library is from top to bottom, just like Python's comprehension.
62+
```rust
63+
let vec = vector![
64+
(top,bottom)
65+
for top in 1..=3 if top != 2
66+
for bottom in 4..=6 if bottom+top != 4];
67+
assert_eq!(vec, vec![(1, 4), (1, 5), (1, 6), (3, 4), (3, 5), (3, 6)]);
68+
```
69+
70+
需要注意的是, 由于在rust中, for loop 是消耗所有权的.
71+
所以通常来说, 对于多层循环, 如果你希望原容器被消耗, 你应该写成如下这样:
72+
Note that in Rust, for loops consume ownership.
73+
So typically, for nested loops, if you want the original container to be consumed, you should write it like this:
74+
75+
```rust
76+
let vec_1 = vec!["ABC".to_string(), "DEF".to_string()];
77+
let vec_2 = vec!["abc".to_string(), "def".to_string()];
78+
let vec_3 = vec![123, 456];
79+
let vec = {
80+
// 遮蔽想消耗的变量
81+
// shadow the variable you want to consume
82+
let vec_1 = vec_1;
83+
let vec_3 = vec_3;
84+
85+
let mut vec = vec![];
86+
// 在外层循环里, 你可以选择使用iter()保留所有权
87+
// In the outer loop, you can choose to use iter() to keep ownership
88+
for i in vec_1.iter() {
89+
if i == "ABC" {
90+
// 在内层循环里, 你必须使用iter() , 否则所有权会在第一次被转移
91+
// In the inner loop, you must use iter(),
92+
// otherwise ownership will be transferred for the first time
93+
for j in vec_2.iter() {
94+
if j == "abc" {
95+
// 如果不使用iter(), 那么vec_3的所有权会在第一次被转移
96+
// If you do not use iter(),
97+
// then the ownership of vec_3 will be transferred for the first time
98+
for k in vec_3.iter() {
99+
if k == &123 {
100+
// 仅在必要时使用clone, 以避免不必要的资源浪费
101+
// Only use clone when necessary to avoid unnecessary resource waste
102+
vec.push((i.clone(), j.clone(), *k));
103+
}
104+
}
105+
}
106+
}
107+
}
108+
}
109+
vec
110+
};
111+
// println!("{:?}", vec_1); // borrow of moved value
112+
println!("{:?}", vec_2); // work well
113+
// println!("{:?}", vec_3); // borrow of moved value
114+
```
115+
116+
但在本库中, 你不需要这么做, 提供的宏会自动帮你处理这些问题.
117+
你唯一需要做的就是在你想要保留所有权的变量后面加上.iter() 或 使用 & , 其余会在宏内自动处理.
118+
But in this library, you don't need to do this, the provided macros will automatically handle these problems for you.
119+
You only need to add .iter() or use & before the variable you want to keep ownership, the rest will be automatically handled in the macro.
120+
```rust
121+
let vec_1 = vec!["ABC".to_string(), "DEF".to_string()];
122+
let vec_2 = vec!["abc".to_string(), "def".to_string()];
123+
let vec_3 = vec![123, 456];
124+
let vec = vector![
125+
(i.clone(),j.clone(),*k)
126+
for i in vec_1 if i == "ABC"
127+
for j in vec_2.iter() if j == "abc"
128+
// for j in &vec_2 if j == "abc" 这种写法也是可以的 this is also reasonable
129+
for k in vec_3 if k == &123
130+
];
131+
// println!("{:?}", vec_1); // borrow of moved value
132+
println!("{:?}", vec_2); // work well
133+
// println!("{:?}", vec_3); // borrow of moved value
134+
```
135+
136+
同时, 该库还支持键值对容器类型, HashMap, BTreeMap
137+
This library also supports key-value collection types, HashMap, BTreeMap
138+
```rust
139+
let vec_key = vec!["key_1".to_string(), "key_2".to_string(), "key_3".to_string()];
140+
let vec_value = [1, 2, 3];
141+
let hash_map = hash_map!{
142+
key.clone() : *value // 三种键值对分隔符都支持
143+
// key.clone() => *value
144+
// key.clone() , *value
145+
for key in vec_key
146+
for value in vec_value
147+
};
148+
assert_eq!(
149+
hash_map,
150+
HashMap::from([
151+
("key_1".to_string(), 3),
152+
("key_2".to_string(), 3),
153+
("key_3".to_string(), 3)
154+
])
155+
);
156+
```
157+
158+
该库也支持迭代器推导式, 但不同于上面的集合推导式, 该迭代器推导式是基于引用的, 所以不会消耗所有权.
159+
除此之外的写法与集合推导式完全相同.
160+
Iterator comprehension is also supported, but unlike the collection comprehension above, this iterator comprehension is based on references, so it will not consume ownership.
161+
```rust
162+
let vec_1 = ["123".to_string(), "456".to_string(), "789".to_string()];
163+
let vec_2 = ["ABC".to_string(), "DEF".to_string(), "GHI".to_string()];
164+
165+
let mut result3 = iterator_ref![
166+
(x.clone(), y.clone()) if x.contains("1") else (y.clone(), x.clone())
167+
for x in vec_1 if x.contains("1") || x.contains("7")
168+
for i in 1..=2
169+
for y in vec_2 if y.contains("D") || x.contains("3")];
170+
171+
for _ in 0..=9 {
172+
println!("{:?}", result3.next());
173+
}
174+
/*
175+
Some(("123", "ABC"))
176+
Some(("123", "DEF"))
177+
Some(("123", "GHI"))
178+
Some(("123", "ABC"))
179+
Some(("123", "DEF"))
180+
Some(("123", "GHI"))
181+
Some(("789", "DEF"))
182+
Some(("789", "DEF"))
183+
None
184+
None
185+
*/
186+
```
187+
188+
以上写法与下面的写法是完全的等价形式
189+
The above writing is equivalent to the following writing
190+
```rust
191+
let vec_1 = ["123".to_string(), "456".to_string(), "789".to_string()];
192+
let vec_2 = ["ABC".to_string(), "DEF".to_string(), "GHI".to_string()];
193+
194+
let mut result3 = {
195+
let vec_2 = vec_2.iter().collect::<Vec<_>>();
196+
let vec_1 = vec_1.iter().collect::<Vec<_>>();
197+
(vec_1)
198+
.into_iter()
199+
.filter_map(move |x| {
200+
(x.contains("1") || x.contains("7"))
201+
.then(|| {
202+
let vec_2 = vec_2.clone();
203+
(1..=2)
204+
.into_iter()
205+
.filter_map(move |i| {
206+
(true)
207+
.then(|| {
208+
let vec_2 = vec_2.clone();
209+
(vec_2)
210+
.into_iter()
211+
.filter_map(move |y| {
212+
(y.contains("D") || x.contains("3"))
213+
.then(|| {
214+
if x.contains("1") {
215+
(x.clone(), y.clone())
216+
} else {
217+
(y.clone(), x.clone())
218+
}
219+
})
220+
})
221+
})
222+
})
223+
})
224+
})
225+
.flatten()
226+
.flatten()
227+
};
228+
```
229+
230+
231+
# some details
232+
233+
vector! :
234+
使用push添加元素
235+
use push to add elements
236+
237+
vec_deque! :
238+
使用push_back添加元素
239+
use push_back to add elements
240+
241+
linked_list! :
242+
使用push_back添加元素
243+
use push_back to add elements
244+
245+
hash_set! :
246+
使用insert添加元素
247+
use insert to add elements
248+
249+
hash_map! :
250+
使用insert添加键值对
251+
use insert to add key-value pairs
252+
253+
b_tree_map! :
254+
使用insert添加键值对
255+
use insert to add key-value pairs
256+
257+
b_tree_set! :
258+
使用insert添加元素
259+
use insert to add elements
260+
261+
binary_heap! :
262+
使用push添加元素
263+
use push to add elements

0 commit comments

Comments
 (0)