Skip to content

Commit dd6f44c

Browse files
committed
borrowing_exerci = "0.3.53"
1 parent 6cbe764 commit dd6f44c

37 files changed

+2149
-295
lines changed

docs/zh-first-volumn/src/hello-borrowing/borrowing-for-loop.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_arr.rs:feature-err }}
2525
```
2626

27-
2827
  在编译该程序以后,编译器给出有用的信息提示,如下所示:
2928

3029
```bash
227 KB
Loading
Binary file not shown.
Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,146 @@
11
# 应用篋:循环for语句可变借用实例
22

3-
https://www.google.com/search?q=rust+mutable+borrow+in+loop&oq=rust+mut+bor&aqs=chrome.3.69i57j0l5.23911j0j7&sourceid=chrome&ie=UTF-8
3+
4+
## 学习内容
5+
- 了解和学习循环for语句可变借用实例
6+
7+
## 篇目
8+
9+
- [方法`into_iter()`与关键词`mut`的组合结构](#方法into_iter与关键词mut的组合结构)
10+
- [方法`iter_mut()`实例](#方法iter_mut实例)
11+
- [题外话](#题外话)
12+
- [方法`next()`实例](#方法next实例)
13+
- [方法`enumerate()`实例](#方法enumerate实例)
14+
- [参考资料](#参考资料)
15+
16+
17+
iter() iterates over the items by reference
18+
into_iter() iterates over the items, moving them into the new scope
19+
iter_mut() iterates over the items, giving a mutable reference to each item
20+
21+
22+
## 方法`into_iter()`与关键词`mut`的组合结构
23+
24+
  对于具有迭代器`Iterator`的对象而言,方法`into_iter()`是完全依赖于其对象类型,且遍历其所有的元素本身。下面通过实例再回顾一下这种方法。
25+
26+
  如下面程序,对象`instance`的类型是`Vec<u8>`,这样其元素是原始类型`u8`,那么方法就遍历其所有原始类型`u8`的元素。
27+
28+
```rust
29+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_into_iter.rs:feature-okay }}
30+
```
31+
32+
  其实,上面程序从表面上,方法`into_iter()`,既看不能让人看到其遍历的元素类型,也看不能让人知道其已经消费了对象`instance`
33+
34+
  对于第一个问题,为了简单快速了解其元素类型,可以使用上面程序注释掉的宏方法`println!()`,要是编译没有错误,就说明对象`item`是引用类型,否则就是非引用类型。
35+
36+
  对于第二个问题,只要在上面程序基础上,在其最后增加一行宏方法`println!()`代码,如下所示。只要编译该程序,就会出现借用编译错误。说明方法`into_iter()`已经把对象`instance`消费掉了。
37+
38+
```rust
39+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_into_iter.rs:feature-error_01 }}
40+
```
41+
42+
  为了使得对象`instance`在调用方法`into_iter()`以后,且修改其元素,而对象`instance`依然存在,需要借用可变对象`instance`
43+
44+
  需要指出的是,即使对象`instance`是可变的,上面程序的方法元素本身也是不可变对象。
45+
46+
  对于方法`into_iter()`,要是对象类型是`&Vec<u8>`,其元素是引用类型`&u8`,那么方法就遍历其所有引用类型`&u8`的元素。
47+
48+
  下面程序可变对象`instance`的类型是`&mut Vec<u8>`,其元素是可变引用类型`&mut u8`,那么方法就遍历其所有可变引用类型`&mut u8`的元素。
49+
50+
  下面程序是这里重点解释的结构。三个部分缺一不可:对象`instance`本身是可变的;其引用本身也是可变的;使用引用作为方法`into_iter()`的对象。这样可以实现对象`instance`内容的修改。
51+
52+
```rust
53+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_into_iter.rs:feature-cp }}
54+
```
55+
56+
  上面程序里,引用对象`ref_instance`的类型是一种默认情况,即绑定对象`ref_instance`时,其类型写与不写是一样的意思。但是下面程序的引用对象`ref_instance`的类型可以不是默认的,而是人为绑定的,这是程序第二段代码的第一行代码。当然程序第二段代码的第二行也是一种默认绑定方式。
57+
58+
  对象`instance`的类型是`&mut [u8]`,其元素是引用类型`&mut u8`,那么方法就遍历其所有引用类型`&mut u8`的元素。这种情况可以把`&Vec<u8>``&[u8]`看作为类似于`&String``&str`
59+
60+
```rust
61+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_into_iter.rs:feature-okey }}
62+
```
63+
64+
## 方法`iter_mut()`实例
65+
66+
> 方法`iter_mut()` = 方法`into_iter()`与关键词`mut`的组合结构
67+
68+
  从上面这行文字可以了解到,接下来说明方法`iter_mut()`其实就是上面程序代码的简化。
69+
70+
  通过下面程序使用方法`iter_mut()`,可以了解到它涉及到下面几方面内容:
71+
72+
- 方法`iter_mut()`遍历其元素都是引用;
73+
- 方法`iter_mut()`遍历其元素都是可变引用;
74+
- 在调用方法`iter_mut()`以后,对象`instance`依然是存在的;
75+
- 方法`iter_mut()`隐藏了一个可变借用对象;
76+
77+
```rust
78+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_iter_mut.rs:feature-ok }}
79+
```
80+
81+
## 题外话
82+
83+
### 方法`enumerate()`实例
84+
85+
  常常希望通过数组的顺序号访问数组。第一个程序说明了这种想法的解决方案:
86+
87+
```rust
88+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_enumerate.rs:feature-cp }}
89+
```
90+
91+
  实现这种想法的比较标准方法是使用标准库方法`enumerate()`。这个方法不仅遍历了数组的顺序号。而且还遍历其所有元素:
92+
93+
```rust
94+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_enumerate.rs:feature-okey }}
95+
```
96+
97+
  第三种是最广泛使用的实现,它摒弃了循环语句:
98+
99+
```rust
100+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_enumerate.rs:feature-okay }}
101+
```
102+
103+
### 方法`next()`实例
104+
105+
  通过下面程序解释使用方法`next()`的技巧:
106+
107+
> 可行结构:可变对象+可变迭代器(iter_mut)+方法`next`
108+
109+
```rust
110+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_next.rs:feature-ok }}
111+
```
112+
113+
> 不可行结构:可变对象+迭代器(iter_mut)+方法`next`
114+
115+
```rust
116+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_next.rs:feature-error_01 }}
117+
```
118+
119+
> 不可行结构:(可变)对象+可变迭代器(into_iter)+方法`next`
120+
121+
```rust
122+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/for_next.rs:feature-error_02 }}
123+
```
124+
125+
## 参考资料
126+
- [rust-for-loop](http://xion.io/post/code/rust-for-loop.html)
127+
- [understanding-rust-loops](https://blog.codeship.com/understanding-rust-loops/)
128+
- [fighting-the-borrow-checker-in-a-loop](https://users.rust-lang.org/t/fighting-the-borrow-checker-in-a-loop/22975)
129+
- [rust-by-example/flow_control](https://doc.rust-lang.org/rust-by-example/flow_control/for.html)
130+
- [whats-the-difference-between-for-x-in-b-and-for-x-in-b-into-iter](https://users.rust-lang.org/t/whats-the-difference-between-for-x-in-b-and-for-x-in-b-into-iter/14739)
131+
- [how-can-i-do-a-mutable-borrow-in-a-for-loop](https://stackoverflow.com/questions/39622783/how-can-i-do-a-mutable-borrow-in-a-for-loop)
132+
- [pointers-in-rust-a-guide](https://words.steveklabnik.com/pointers-in-rust-a-guide)
133+
- [rust-ref](https://jvns.ca/blog/2017/11/27/rust-ref/)
134+
- [search?q=rust+mutable+borrow+in+loop](https://www.google.com/search?q=rust+mutable+borrow+in+loop)
135+
- [what-is-the-difference-between-iter-and-into-iter](https://stackoverflow.com/questions/34733811/what-is-the-difference-between-iter-and-into-iter)
136+
- [a-journey-into-iterators](https://hoverbear.org/blog/a-journey-into-iterators/)
137+
- [yarit-yet-another-rust-iterators-tutorial](https://dev.to/dandyvica/yarit-yet-another-rust-iterators-tutorial-46dk)
138+
- [effectively-using-iterators-in-rust](https://hermanradtke.com/2015/06/22/effectively-using-iterators-in-rust.html)
139+
-
140+
141+
142+
```rust
143+
{{ #include ../../../../hello-borrowing/bin-hello/examples/for_loop/mut_string.rs:feature-okey }}
144+
```
145+
146+
![image](../../hello-borrowing/images/hello_borrowing-12_vec_for_loop.png)

docs/zh-first-volumn/src/hello-mut-borrowing/borrowing-mut.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
## 学习内容
66
- 了解和学习绑定固定引用和可变引用的可变对象借用实例
77

8-
98
## 篇目
109

1110
- [可变对象及其可变引用关系](#可变对象及其可变引用关系)
@@ -97,35 +96,32 @@ let mut mut_ref_immut :&str = &instance;
9796

9897
## 绑定可变引用的可变对象
9998

100-
10199
> let mut mut_and_mut_ref = &mut mut_instance;
102100
103-
```rust
104-
{{ #include ../../../../hello-borrowing/bin-hello/examples/mut_immut/mut_string.rs:feature-okey }}
105-
```
106-
101+
  与前面了解到的绑定可变引用的固定对象与绑定固定引用的可变对象实例类似,这种如上Rust语句的对象`mut_and_mut_ref`,无论是所引用对象`mut_instance`值,还是对象`mut_and_mut_ref`本身值都是可变的。
107102

103+
  下面是如何使用绑定可变引用的可变对象具体实例:
108104

109-
```
110-
// https://internals.rust-lang.org/t/allow-mut-value-not-just-mut-reference/7424/2
111-
let mut a = &mut x;
105+
```rust
106+
{{ #include ../../../../hello-borrowing/bin-hello/examples/mut_immut/mut_string.rs:feature-okey }}
112107
```
113108

114-
You can also do let mut a = &mut x; which would mean you could later change a to be a mutable reference to another variable.
115-
A mut after let means the variable can be changed. This is not equivalent to a mut at any place right of the =.
109+
  在这里之所以使用可变对象属性,是因为在第一次调用方法`one()`以后,方法将对象`mut_ref`消费掉了,尽管对象`mut_ref`本身还是存在的,但其内容已经不在了,要是直接再次调用方法`two()`,就会出现错误。这也说明了对象`mut_ref`的值是可变的。
116110

111+
  要是不存在对象`mut_ref`第二次的赋值,就会出现下面借用错误。
117112

118-
https://hermanradtke.com/2015/06/09/strategies-for-solving-cannot-move-out-of-borrowing-errors-in-rust.html
119113

120114

121-
borrow-clone.rs
115+
  在这里之所以使用需要绑定可变引用属性,是因为调用方法的参数是可变引用。方法参数是可变引用,说明该引用将会被修改。从方法功能可以看到,参数是被修改了。
122116

117+
  通过上面了解到绑定可变引用的可变对象,不仅对象`mut_ref`本身内容是可修改的,即,之后可以将其更改为另一个对象或者其本身的可变引用,而且其值的对象`mut_instance`内容也是可修改的,即,之后可以将其更改为任何字符串文字内容。
123118

124-
Can you spot the difference? Now, on line 4, we call the other function with a clone of the value held by the hello variable. Obviously this is not the most efficient way to write your program, and it can be risky if you don't know the size of the values which are going to be getting cloned. Also, if your functions mutate the value in some way then this is not a good solution:
119+
  最后非常简单地阐述类型`Box<T>`的作用,类型`Box<T>`可以将任何类型`T`打包起来,方便其打包类型`T`进行传输或者处理等,比如,要是一组不同类型都打包成类型`Box<T>`以后,就可以作为一个数组一起处理,另外这是一种引用数据类型。
125120

126-
您看得出来差别吗? 现在,在第4行,我们用hello变量保存的值的克隆调用另一个函数。 显然,这不是编写程序的最有效方法,如果您不知道将要克隆的值的大小,则可能会有风险。 另外,如果您的函数以某种方式更改了值,那么这不是一个好的解决方案:
121+
  可以把类型`Box<T>``T`理解为类型`String``str`的类似关系,前者类型`String`存在可以大量操作其内容的功能,而后者主要的内容储存功能,两种各自具有不同的功能。当然类型`Box<T>`主要的解压功能,而后者是数据结构功能。
127122

128123
## 题外话
124+
129125
### 连接字符串的正确方法
130126

131127
```rust
@@ -142,11 +138,6 @@ println!("result = {}", result);
142138
```
143139

144140

145-
- [what-is-right-ways-to-concat-strings](https://users.rust-lang.org/t/what-is-right-ways-to-concat-strings/3780/1)
146-
- [best-way-to-do-string-concatenation-in-2019-status-quo](https://users.rust-lang.org/t/best-way-to-do-string-concatenation-in-2019-status-quo/24004)
147-
- [how-do-i-concatenate-strings](https://stackoverflow.com/questions/30154541/how-do-i-concatenate-strings)
148-
-
149-
150141
## 最主要参考资料
151142
- [rust-ownership](https://hellocode.dev/rust-ownership)
152143
- [passing-a-string-by-reference-and-manipulate-the-string](https://stackoverflow.com/questions/26151324/passing-a-string-by-reference-and-manipulate-the-string)
@@ -160,4 +151,11 @@ println!("result = {}", result);
160151
- [strategies-for-solving-cannot-move-out-of-borrowing-errors-in-rust](https://hermanradtke.com/2015/06/09/strategies-for-solving-cannot-move-out-of-borrowing-errors-in-rust.html)
161152
- [best-way-to-do-string-concatenation-in-2019-status-quo](https://users.rust-lang.org/t/best-way-to-do-string-concatenation-in-2019-status-quo/24004/4)
162153
- [what-is-right-ways-to-concat-strings](https://users.rust-lang.org/t/what-is-right-ways-to-concat-strings/3780)
163-
-
154+
- [allow-mut-value-not-just-mut-reference](https://internals.rust-lang.org/t/allow-mut-value-not-just-mut-reference/7424/2)
155+
- [strategies-for-solving-cannot-move-out-of-borrowing-errors-in-rust](https://hermanradtke.com/2015/06/09/strategies-for-solving-cannot-move-out-of-borrowing-errors-in-rust.html)
156+
157+
## 参考资料:题外话
158+
159+
- [what-is-right-ways-to-concat-strings](https://users.rust-lang.org/t/what-is-right-ways-to-concat-strings/3780/1)
160+
- [best-way-to-do-string-concatenation-in-2019-status-quo](https://users.rust-lang.org/t/best-way-to-do-string-concatenation-in-2019-status-quo/24004)
161+
- [how-do-i-concatenate-strings](https://stackoverflow.com/questions/30154541/how-do-i-concatenate-strings)

docs/zh-volumn-one/hello-borrowing/borrowing-for-loop.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ <h2><a class="header" href="#固定数组的借用错误实例" id="固定数组
171171
<pre><pre class="playpen"><code class="language-rust">
172172
# #![allow(unused_variables)]
173173
#fn main() {
174-
// File: ./bin-hello/examples/for_loop/for_arr/mod.rs
174+
// File: ./bin-hello/examples/for_loop/for_arr.rs
175175
// #[cfg(feature = &quot;err_01&quot;)]
176176

177177
let instance = [1u8, 2, 3];
@@ -201,7 +201,7 @@ <h2><a class="header" href="#固定数组的借用机制实例" id="固定数组
201201
<pre><pre class="playpen"><code class="language-rust">
202202
# #![allow(unused_variables)]
203203
#fn main() {
204-
// File: ./bin-hello/examples/for_loop/for_arr/mod.rs
204+
// File: ./bin-hello/examples/for_loop/for_arr.rs
205205
// #[cfg(feature = &quot;ok&quot;)]
206206

207207
let instance = [1u8, 2, 3];
@@ -257,7 +257,7 @@ <h2><a class="header" href="#可变数组的简单借用错误实例" id="可变
257257
# #![allow(unused_variables)]
258258
#fn main() {
259259
pub fn adjoin() {
260-
// File: ./bin-hello/examples/for_loop/for_vec/mod.rs
260+
// File: ./bin-hello/examples/for_loop/for_vec.rs
261261
// #[cfg(feature = &quot;cp&quot;)]
262262

263263
let instance = vec![1, 2, 3];
@@ -283,7 +283,7 @@ <h2><a class="header" href="#可变数组的简单借用错误实例" id="可变
283283
<pre><pre class="playpen"><code class="language-rust">
284284
# #![allow(unused_variables)]
285285
#fn main() {
286-
// File: ./bin-hello/examples/for_loop/for_vec/mod.rs
286+
// File: ./bin-hello/examples/for_loop/for_vec.rs
287287
// #[cfg(feature = &quot;err_02&quot;)]
288288

289289
let instance = vec![1, 2, 3];
@@ -304,7 +304,7 @@ <h2><a class="header" href="#可变数组的借用机制实例" id="可变数组
304304
<pre><pre class="playpen"><code class="language-rust">
305305
# #![allow(unused_variables)]
306306
#fn main() {
307-
// File: ./bin-hello/examples/for_loop/for_vec/mod.rs
307+
// File: ./bin-hello/examples/for_loop/for_vec.rs
308308
// #[cfg(feature = &quot;ok&quot;)]
309309

310310
let instance = vec![1u8, 2, 3];
@@ -335,7 +335,7 @@ <h2><a class="header" href="#迭代方法iter和into_iter区别" id="迭代方
335335
<pre><pre class="playpen"><code class="language-rust">
336336
# #![allow(unused_variables)]
337337
#fn main() {
338-
// File: ./bin-hello/examples/for_loop/for_vec_iter/mod.rs
338+
// File: ./bin-hello/examples/for_loop/for_vec_iter.rs
339339
// #[cfg(feature = &quot;err_03&quot;)]
340340

341341
let instance = vec![1, 2, 3];
@@ -361,7 +361,7 @@ <h2><a class="header" href="#迭代方法iter和into_iter区别" id="迭代方
361361
<pre><pre class="playpen"><code class="language-rust">
362362
# #![allow(unused_variables)]
363363
#fn main() {
364-
// File: ./bin-hello/examples/for_loop/for_vec_iter/mod.rs
364+
// File: ./bin-hello/examples/for_loop/for_vec_iter.rs
365365
// #[cfg(feature = &quot;cp&quot;)]
366366

367367
let instance = vec![1u8, 2, 3];
@@ -397,7 +397,7 @@ <h2><a class="header" href="#可变数组的迭代借用机制实例" id="可变
397397
<pre><pre class="playpen"><code class="language-rust">
398398
# #![allow(unused_variables)]
399399
#fn main() {
400-
// File: ./bin-hello/examples/for_loop/for_vec_iter/mod.rs
400+
// File: ./bin-hello/examples/for_loop/for_vec_iter.rs
401401
// #[cfg(feature = &quot;ok&quot;)]
402402

403403
let instance = vec![1u8, 2, 3];
227 KB
Loading
Binary file not shown.

0 commit comments

Comments
 (0)