Skip to content

Commit 3340355

Browse files
添加中文README.md
1 parent 109c4a2 commit 3340355

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

README-CN.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# better_comprehension
2+
3+
在rust中的集合推导式和迭代器推导式。提供更好的Rust使用体验
4+
5+
# 用法
6+
语法源自[python推导式](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions)
7+
8+
本库为Rust标准库中的所有集合类型提供宏,以及基于引用的迭代器
9+
10+
---
11+
简单示例
12+
13+
```rust
14+
let vec_1 = vec!["AB".to_string(), "CD".to_string()];
15+
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+
你也可以在推导式中使用模式
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+
30+
let vec_deque = vec_deque![name.clone() for Person { name, .. } in people];
31+
assert_eq!(vec_deque, VecDeque::from(["Joe".to_string(), "Bob".to_string()]));
32+
```
33+
---
34+
35+
过滤集合中的值
36+
```rust
37+
let linked_list = linked_list![ i*2 for i in 1..=3 if i != 2 ];
38+
assert_eq!(linked_list, LinkedList::from([2, 6]));
39+
```
40+
---
41+
42+
根据条件返回不同的值
43+
```rust
44+
let b_tree_set = b_tree_set!{
45+
i if i-1 == 0 else i+10
46+
for i in 1..=3 if i != 2
47+
};
48+
assert_eq!(b_tree_set, BTreeSet::from([1, 13]));
49+
```
50+
51+
---
52+
嵌套推导式
53+
```rust
54+
let binary_heap = binary_heap![
55+
i if (i-1 == 0 || j -2 == 0) else i+10
56+
for i in 1..=3 if i != 2
57+
for j in 1..=3 if j+i != 4];
58+
assert_eq!(binary_heap.into_sorted_vec(), vec![1, 1, 3, 13]);
59+
```
60+
---
61+
62+
和python的推导式一样, 本库的for循环是从上到下读取的.
63+
```rust
64+
let vec = vector![
65+
(top,bottom)
66+
for top in 1..=3 if top != 2
67+
for bottom in 4..=6 if bottom+top != 4];
68+
assert_eq!(vec, vec![(1, 4), (1, 5), (1, 6), (3, 4), (3, 5), (3, 6)]);
69+
```
70+
71+
需要注意的是, 由于在rust中, for loop 是消耗所有权的.
72+
73+
所以通常来说, 对于多层循环, 如果你希望原容器被消耗, 你应该写成如下这样:
74+
```rust
75+
let vec_1 = vec!["ABC".to_string(), "DEF".to_string()];
76+
let vec_2 = vec!["abc".to_string(), "def".to_string()];
77+
let vec_3 = vec![123, 456];
78+
let vec = {
79+
// 遮蔽想消耗的变量
80+
let vec_1 = vec_1;
81+
let vec_3 = vec_3;
82+
83+
let mut vec = vec![];
84+
// 在外层循环里, 你可以选择使用iter()保留所有权
85+
for i in vec_1.iter() {
86+
if i == "ABC" {
87+
// 在内层循环里, 你必须使用iter() , 否则所有权会在第一次被转移
88+
for j in vec_2.iter() {
89+
if j == "abc" {
90+
// 如果不使用iter(), 那么vec_3的所有权会在第一次被转移
91+
for k in vec_3.iter() {
92+
if k == &123 {
93+
// 仅在必要时使用clone, 以避免不必要的资源浪费
94+
vec.push((i.clone(), j.clone(), *k));
95+
}
96+
}
97+
}
98+
}
99+
}
100+
}
101+
vec
102+
};
103+
// println!("{:?}", vec_1); // borrow of moved value
104+
println!("{:?}", vec_2); // work well
105+
// println!("{:?}", vec_3); // borrow of moved value
106+
```
107+
108+
但在本库中, 你不需要这么做, 提供的宏会自动帮你处理这些问题.
109+
110+
你唯一需要做的就是在你想要保留所有权的变量后面加上.iter() 或 使用 & , 其余会在宏内自动处理.
111+
```rust
112+
let vec_1 = vec!["ABC".to_string(), "DEF".to_string()];
113+
let vec_2 = vec!["abc".to_string(), "def".to_string()];
114+
let vec_3 = vec![123, 456];
115+
116+
let vec = vector![
117+
(i.clone(),j.clone(),*k)
118+
for i in vec_1 if i == "ABC"
119+
for j in vec_2.iter() if j == "abc"
120+
// for j in &vec_2 if j == "abc" 这种写法也是可以的
121+
for k in vec_3 if k == &123
122+
];
123+
// println!("{:?}", vec_1); // borrow of moved value
124+
println!("{:?}", vec_2); // work well
125+
// println!("{:?}", vec_3); // borrow of moved value
126+
```
127+
128+
同时, 该库还支持键值对容器类型, HashMap, BTreeMap
129+
130+
```rust
131+
let vec_key = vec!["key_1".to_string(), "key_2".to_string(), "key_3".to_string()];
132+
let vec_value = [1, 2, 3];
133+
let hash_map = hash_map!{
134+
key.clone() : *value // 三种键值对分隔符都支持
135+
// key.clone() => *value
136+
// key.clone() , *value
137+
for key in vec_key
138+
for value in vec_value
139+
};
140+
assert_eq!(
141+
hash_map,
142+
HashMap::from([
143+
("key_1".to_string(), 3),
144+
("key_2".to_string(), 3),
145+
("key_3".to_string(), 3)
146+
])
147+
);
148+
```
149+
---
150+
151+
该库也支持迭代器推导式, 但不同于上面的集合推导式
152+
153+
该迭代器推导式是基于引用的, 所以不会消耗所有权
154+
155+
除此之外的写法与集合推导式完全相同
156+
```rust
157+
let vec_1 = ["123".to_string(), "456".to_string(), "789".to_string()];
158+
let vec_2 = ["ABC".to_string(), "DEF".to_string(), "GHI".to_string()];
159+
160+
let mut result3 = iterator_ref![
161+
(x.clone(), y.clone()) if x.contains("1") else (y.clone(), x.clone())
162+
for x in vec_1 if x.contains("1") || x.contains("7")
163+
for i in 1..=2
164+
for y in vec_2 if y.contains("D") || x.contains("3")];
165+
166+
167+
for _ in 0..=9 {
168+
println!("{:?}", result3.next());
169+
}
170+
/*
171+
Some(("123", "ABC"))
172+
Some(("123", "DEF"))
173+
Some(("123", "GHI"))
174+
Some(("123", "ABC"))
175+
Some(("123", "DEF"))
176+
Some(("123", "GHI"))
177+
Some(("789", "DEF"))
178+
Some(("789", "DEF"))
179+
None
180+
None
181+
*/
182+
```
183+
184+
以上写法与下面的写法是完全的等价形式
185+
```rust
186+
let vec_1 = ["123".to_string(), "456".to_string(), "789".to_string()];
187+
let vec_2 = ["ABC".to_string(), "DEF".to_string(), "GHI".to_string()];
188+
189+
let mut result3 = {
190+
let vec_2 = vec_2.iter().collect::<Vec<_>>();
191+
let vec_1 = vec_1.iter().collect::<Vec<_>>();
192+
(vec_1).into_iter().filter_map(move |x| {
193+
(x.contains("1") || x.contains("7")).then(|| {
194+
let vec_2 = vec_2.clone();
195+
(1..=2).into_iter().filter_map(move |i| {
196+
(true).then(|| {
197+
let vec_2 = vec_2.clone();
198+
(vec_2).into_iter().filter_map(move |y| {
199+
(y.contains("D") || x.contains("3")).then(|| {
200+
if x.contains("1") {
201+
(x.clone(), y.clone())
202+
} else {
203+
(y.clone(), x.clone())
204+
}
205+
})
206+
})
207+
})
208+
})
209+
})
210+
.flatten()
211+
.flatten()
212+
};
213+
```
214+
215+
216+
# 一些细节
217+
218+
vector! : 使用push()添加元素
219+
220+
vec_deque! : 使用push_back()添加元素
221+
222+
linked_list! : 使用push_back()添加元素
223+
224+
hash_set! : 使用insert()添加元素
225+
226+
hash_map! : 使用insert()添加键值对
227+
228+
b_tree_map! : 使用insert()添加键值对
229+
230+
b_tree_set! : 使用insert()添加元素
231+
232+
binary_heap! : 使用push()添加元素

0 commit comments

Comments
 (0)