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 <==> &copy  ===>  HashSet::get()
362                // &copy_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}