sui_rust/ch02/s2_lifetime.rs
1//! 第二章:Rust核心概念
2//! 2.2 生命周期与借用检查
3//!
4//! 借用检查相关代码
5
6/**
7 ### 理解词法作用域
8
9 基本数据类型: https://doc.rust-lang.org/std/index.html#primitives
10
11 ```
12 fn main(){
13 let mut v = vec![];
14 v.push(1);
15 {
16 println!("{:?}", v[0]);
17 v.push(2);
18 }
19 }
20 ```
21*/
22pub fn understand_scope() {
23 println!(" 理解词法作用域 ");
24}
25
26/**
27 ### 理解借用检查 NLL
28
29 示例:替换字符串中的问号
30
31 ```
32 fn main(){
33 let s = "abc?d";
34 let mut chars = s.chars().collect::<Vec<char>>();
35
36 // 处理字符串
37 for (i, c) in chars.iter_mut().enumerate() {
38 // 定义 a-z 字母集
39 let mut words = ('a'..='z').into_iter();
40 // 此处 `chars[i]` 是对chars的不可变借用
41 if chars[i] == '?' {
42 // 此处 `chars[i]` 是对chars的不可变借用
43 let left = if i==0 {None} else { Some(chars[i-1]) };
44 // 此处 `chars[i]` 是对chars的不可变借用
45 let right = if i==s.len()-1 {None} else {Some(chars[i+1])};
46 // 此处 `chars[i]` 是对chars的可变借用,要修改chars数组了
47 // 从a-z 字母集中查找和左右两边不一样的字母去替换当前字符,避免重复
48 chars[i] = words.find(|&w| Some(w) != left && Some(w) != right).unwrap();
49 }
50 }
51
52 let s = chars.into_iter().collect::<String>();
53 println!("{:?}", s);
54 }
55 ```
56*/
57pub fn understand_nll() {
58 println!(" 理解 非词法作用域借用检查: NLL ");
59}
60
61/**
62
63 理解普通生命周期参数:
64
65 说明: 生命周期参数:late bound vs early bound
66
67 示例1:
68
69 ```rust
70 fn return_str<'a>() -> &'a str {
71 let mut s = "Rust".to_string();
72 for i in 0..3 {
73 s.push_str("Good ");
74 }
75 &s[..] //"Rust Good Good Good"
76 }
77 fn main() {
78 let x = return_str();
79 }
80
81 ```
82
83 示例2:
84
85 ```rust
86 fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
87 let result = String::from("really long string");
88 // error
89 result.as_str()
90 }
91
92 fn main() {
93 let x = "hello";
94 let y = "rust";
95 foo(x, y);
96 }
97 ```
98
99 示例3:
100
101 ```rust
102 fn the_longest(s1: &str, s2: &str) -> &str {
103 if s1.len() > s2.len() { s1 } else { s2 }
104 }
105 fn main() {
106 let s1 = String::from("Rust");
107 let s1_r = &s1;
108 {
109 let s2 = String::from("C");
110 let res = the_longest(s1_r, &s2);
111 println!("{} is the longest", res);
112 }
113
114 ```
115
116 示例4:
117
118 ```rust
119 fn the_longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
120 if s1.len() > s2.len() { s1 } else { s2}
121 }
122 fn main() {
123 let s1 = String::from("Rust");
124 let s1_r = &s1;
125 {
126 let s2 = String::from("C");
127 let res = the_longest(s1_r, &s2);
128 println!("{} is the longest", res); // Rust is the longest
129 }
130
131 ```
132*/
133pub fn understand_lifetime() {
134 println!(" 理解 生命周期参数 ");
135}
136
137/**
138
139说明: 生命周期参数:late bound vs early bound
140
141Quiz 11: [https://dtolnay.github.io/rust-quiz/11](https://dtolnay.github.io/rust-quiz/11)
142
143
144```rust
145
146fn f<'a>() {}
147fn g<'a: 'a>() {}
148
149fn main() {
150 let pf = f::<'static> as fn(); // late bound
151 let pg = g::<'static> as fn(); // early bound
152 print!("{}", pf == pg);
153}
154
155```
156
157
158示例一:late bound lifetime
159
160```rust
161struct Buffer {
162 buf: Vec<u8>,
163 pos: usize,
164}
165
166impl Buffer {
167 fn new() -> Buffer {
168 Buffer {
169 buf: vec![1,2,3, 4, 5,6],
170 pos: 0,
171 }
172 }
173
174 fn read_bytes<'a>(&'a mut self) -> &'a [u8] {
175 self.pos += 3;
176 &self.buf[self.pos-3..self.pos]
177 }
178}
179
180fn print(b1 :&[u8], b2: &[u8]) {
181 println!("{:#?} {:#?}", b1, b2)
182}
183
184fn main() {
185 let mut buf = Buffer::new();
186 // let b1 = buf.read_bytes(); // don't work
187 let b1 = &(buf.read_bytes().to_owned());
188 let b2 = buf.read_bytes();
189 print(b1,b2)
190}
191```
192
193示例二: early bound lifetime
194
195```rust
196fn main() {
197 let v = vec![1,2,3, 4, 5,6];
198 let mut buf = Buffer::new(&v);
199 let b1 = buf.read_bytes();
200 // let b1 = &buf.read_bytes().to_owned();
201 let b2 = buf.read_bytes();
202 print(b1,b2)
203}
204
205fn print(b1 :&[u8], b2: &[u8]) {
206 println!("{:#?} {:#?}", b1, b2)
207}
208
209struct Buffer<'a> {
210 buf: &'a [u8],
211 pos: usize,
212}
213
214impl<'b, 'a: 'b> Buffer<'a> {
215 fn new(b: &'a [u8]) -> Buffer {
216 Buffer {
217 buf: b,
218 pos: 0,
219 }
220 }
221
222 fn read_bytes(&'b mut self) -> &'a [u8] {
223 self.pos += 3;
224 &self.buf[self.pos-3..self.pos]
225 }
226}
227```
228*/
229pub fn understand_lifetime_early_late_bound() {
230 println!(" 理解生命周期参数:early bound vs late bound ");
231}
232
233/**
234
235 ### 闭包 与 高阶生命周期
236
237 ```rust
238
239 fn main() {
240 let f = |x: &i32| x; // error
241 // 假如支持下面的语法就方便多了,目前还未支持
242 // let f: for<'a> Fn(&'a i32) -> &'a i32 = |x| x;
243 let i = &3;
244 let j = f(i);
245 }
246
247 ```
248
249 修正:
250
251 相关:[Explicit lifetime bounds RFC 0192](https://rust-lang.github.io/rfcs/0192-bounds-on-object-and-generic-types.html)
252 ```rust
253
254 // fn annotate<'a, T: 'a ,F>(f: F) -> F where F: Fn(&'a T) -> &'a T { f }
255
256 fn annotate<T,F>(f: F) -> F where for<'a> F: Fn(&'a T) -> &'a T { f }
257
258 fn main() {
259 let f = annotate(|x| x);
260 let i = &3;
261 let j = f(i);
262 assert_eq!(*j, 3);
263 }
264
265 ```
266*/
267pub fn understand_lifetime_for_closure() {
268 println!(" 理解生命周期参数: 闭包相关")
269}
270
271/**
272
273 ### 理解 T vs &T
274
275 ```rust
276 use std::fmt::Debug;
277
278 #[derive(Debug)]
279 struct Ref<'a, T: 'a>(&'a T);
280
281 fn print<T>(t: T)
282 where
283 T: Debug,
284 {
285 println!("`print`: t is {:?}", t);
286 }
287
288 fn print_ref<'a, T>(t: &'a T)
289 where
290 T: Debug + 'a,
291 {
292 println!("`print_ref`: t is {:?}", t);
293 }
294
295 fn main() {
296 let x = 7;
297 let ref_x = Ref(&x);
298 print_ref(&ref_x);
299 print(ref_x);
300 }
301 ```
302
303 示例:Rust Quiz 5 :[https://zhuanlan.zhihu.com/p/51616607](https://zhuanlan.zhihu.com/p/51616607)
304
305 以下代码输出什么?
306
307 ```rust
308 trait Trait {
309 fn f(self);
310 }
311
312 impl<T> Trait for fn(T) {
313 fn f(self) {
314 print!("1");
315 }
316 }
317
318 impl<T> Trait for fn(&T) {
319 fn f(self) {
320 print!("2");
321 }
322 }
323
324 fn main() {
325 let a: fn(_) = |_: u8| {};
326 let b: fn(_) = |_: &u8| {};
327 let c: fn(&_) = |_: &u8| {};
328 a.f();
329 b.f();
330 c.f();
331 }
332 ```
333
334 示例:来自于社区 Potato TooLarge 的案例
335
336 [https://zhuanlan.zhihu.com/p/194156624](https://zhuanlan.zhihu.com/p/194156624)
337
338 ```rust
339
340 // https://doc.rust-lang.org/std/collections/struct.HashSet.html
341
342 use std::collections::HashSet;
343
344 fn main() {
345
346 let hello = "hello".to_owned();
347 let mut items = HashSet::new();
348
349 items.insert(hello.as_str());
350
351 let mut global_set = HashSet::new();
352 global_set.insert(hello.as_str());
353
354 while !global_set.is_empty() {
355 let mut temp_set = HashSet::new();
356
357 for &item in global_set.iter() {
358 let copy = item.to_owned();
359 let copy_str = copy.as_str();
360
361 // copy_str <==> © ===> HashSet::get()
362 // ©_str <==> &'x &'a copy
363
364 if let Some(inner) = items.get(copy_str).cloned() {
365 temp_set.insert(inner);
366 };
367 };
368 std::mem::swap(&mut global_set, &mut temp_set);
369 break;
370 };
371 }
372 ```
373
374
375*/
376pub fn understand_lifetime_in_generic_type() {
377 println!(" 理解生命周期参数:T vs &T ");
378}
379
380/**
381
382 示例: 理解 trait对象中的生命周期参数
383
384 ```rust
385 trait Foo<'a> {}
386 struct FooImpl<'a> {
387 s: &'a [u32],
388 }
389 impl<'a> Foo<'a> for FooImpl<'a> {
390 }
391 // 为 trait对象 增加 'a ,因为 Box 默认是 static 的,而FooImpl 中的 s 则是引用
392 // 表明该trait对象(结构体实例)与其结构体中的引用的生命周期是一样长的(<=)
393 fn foo<'a>(s: &'a [u32]) -> Box<dyn Foo<'a> + 'a> {
394 Box::new(FooImpl { s: s })
395 }
396 fn main(){}
397 ```
398
399 ### 理解 HRTB (higher ranked trait bounds)
400
401 示例一:
402
403 ```rust
404 use std::fmt::Debug;
405 trait DoSomething<T> {
406 fn do_sth(&self, value: T);
407 }
408 impl<'a, T: Debug> DoSomething<T> for &'a usize {
409 fn do_sth(&self, value: T) {
410 println!("{:?}", value);
411 }
412 }
413 fn foo<'a>(b: Box<DoSomething<&'a usize>>) {
414 let s: usize = 10;
415 b.do_sth(&s) // error[E0597]: `s` does not live long enough
416 }
417 fn main(){
418 let x = Box::new(&2usize);
419 foo(x);
420 }
421 ```
422
423 修正:使用 `for<'f>` 改为 late bound
424
425 ```rust
426
427 use std::fmt::Debug;
428 trait DoSomething<T> {
429 fn do_sth(&self, value: T);
430 }
431 impl<'a, T: Debug> DoSomething<T> for &'a usize {
432 fn do_sth(&self, value: T) {
433 println!("{:?}", value);
434 }
435 }
436 fn bar(b: Box<for<'f> DoSomething<&'f usize>>) {
437 let s: usize = 10;
438 b.do_sth(&s);
439 }
440 fn main(){
441 let x = Box::new(&2usize);
442 bar(x);
443 }
444 ```
445
446 示例 2:
447
448 ```rust
449 use rand;
450 use std::io::Read;
451
452 trait Checksum<R: Read> {
453 fn calc(&mut self, r: R) -> Vec<u8>;
454 }
455
456 struct Xor;
457
458 impl<R: Read> Checksum<R> for Xor {
459 fn calc(&mut self, mut r: R) -> Vec<u8> {
460 let mut res: u8 = 0;
461 let mut buf = [0u8; 8];
462 loop {
463 let read = r.read(&mut buf).unwrap();
464 if read == 0 {
465 break;
466 }
467 for b in &buf[..read] {
468 res ^= b;
469 }
470 }
471
472 vec![res]
473 }
474 }
475
476 struct Add;
477
478 impl<R: Read> Checksum<R> for Add {
479 fn calc(&mut self, mut r: R) -> Vec<u8> {
480 let mut res: u8 = 0;
481 let mut buf = [0u8; 8];
482 loop {
483 let read = r.read(&mut buf).unwrap();
484 if read == 0 {
485 break;
486 }
487 for b in &buf[..read] {
488 let tmp = res as u16 + *b as u16;
489 res = tmp as u8;
490 }
491 }
492
493 vec![res]
494 }
495 }
496
497 fn main() {
498 let mut buf = [0u8; 8];
499 // error[E0308]: `if` and `else` have incompatible types
500 // 修正:
501 // step 1: Box<dyn Checksum<&[u8]>> 转为 trait 对象
502 // step 2: Box<dyn for<'a> Checksum<&'a [u8]>> 使用 for<'a> 转为 late bound
503 let mut checker = if rand::random() {
504 println!("Initializing Xor Checksum");
505 Box::new(Xor)
506 } else {
507 println!("Initializing Add Checksum");
508 Box::new(Add)
509 };
510
511 let mut data = "Sedm lumpu slohlo pumpu za uplnku".as_bytes();
512 let mut i = 0;
513
514 loop {
515 let chunk_size = data.read(&mut buf).unwrap();
516 if chunk_size == 0 {
517 break;
518 }
519 let cs = checker.calc(&buf[..chunk_size]);
520 println!("Checksum {} is {:?}", i, cs);
521 i += 1;
522 }
523 }
524 ```
525
526
527
528*/
529pub fn understand_lifetime_hrtb() {
530 println!(" 理解生命周期参数:HRTB (higher ranked trait bounds) ");
531}