sui_rust/ch02/
s1_ownership.rs

1//! 第二章:Rust核心概念
2//! 2.1 安全管理之内存安全
3//!
4//! 所有权相关代码
5//!
6//!  String 结构:
7//!  
8//!  ```text
9//!  ---  
10//!                   buffer
11//!                  /   capacity
12//!                 /   /  length
13//!                /   /   /
14//!              +–––+–––+–––+
15//!  stack frame │ • │ 8 │ 6 │ <- my_name: String
16//!              +–│–+–––+–––+
17//!                │
18//!              [–│–––––––– capacity –––––––––––]
19//!                │
20//!              +–V–+–––+–––+–––+–––+–––+–––+–––+
21//!  heap        │ P │ a │ s │ c │ a │ l │   │   │
22//!              +–––+–––+–––+–––+–––+–––+–––+–––+
23//!              [––––––– length ––––––––]
24//!   
25//!  &'static str 结构:
26//!              [–––––––––––]
27//!              +–––+–––+
28//!  stack frame │ • │ 6 │
29//!              +–│–+–––+
30//!                │                 
31//!                +––+                
32//!                   │
33//!  preallocated   +–V–+–––+–––+–––+–––+–––+
34//!  read-only      │ P │ a │ s │ c │ a │ l │
35//!  memory         +–––+–––+–––+–––+–––+–––+
36//!  ```
37
38/**
39    ### Rust 语义:Move 语义 与 Copy 语义
40
41    基本数据类型: https://doc.rust-lang.org/std/index.html#primitives
42
43    ```
44    fn main(){
45        // impl Copy for i32
46        let a = 42;
47        let b = a;
48        println!("{:?}", a);  // work
49
50        // impl Copy for &'static str
51        let a = "42";
52        let b = a;
53        println!("{:?}", a); // work
54
55        // impl !Copy for String
56        let a = "42".to_string();
57        // &String deref to &str
58        let b : &str = &a;
59        // impl Copy for &'a T
60        let c = b;
61        println!("{:?}", b); // work
62
63        // impl !Copy for String
64        let mut a = "42".to_string();
65        // impl !Copy for &mut T
66        let b : &mut str = &mut a;
67        let c = b;
68        // println!("{:?}", b); // don't work, b have been moved
69
70        // auto impl Copy for Tuple, if all item implemented Copy trait in Tuple
71        let t = (42, "42");
72        let t2 = t;
73        println!("{:?}", t); // work
74
75        // auto impl !Copy for Tuple
76        let t = (42, "42".to_string());
77        let t2 = t;
78        // println!("{:?}", t); // don't work, t have been moved
79    }
80    ```
81*/
82pub fn primitive_types() {
83    println!(" Copy 和 Move 语义: 基础数据类型实现 Copy 的一些情况 ");
84}
85
86/**
87    ### Rust 语义:Move 语义 与 Copy 语义
88
89    自定义数据类型:
90
91    ```
92    // #[derive(Copy, Clone)]
93    struct A;
94
95    // #[derive(Copy, Clone)]
96    struct Point(u32);
97
98    // #[derive(Copy, Clone)]
99    struct Member {
100        name: &'static str,
101        age: u32,
102    }
103
104    // #[derive(Copy, Clone)]
105    struct Person {
106        name: String,
107        age: u32,
108    }
109
110    fn main(){
111        let a = A;
112        let b = a;
113        println!("{:?}", a);  // work
114
115        let a = Point(60);
116        let b = a;
117        println!("{:?}", a);  // work
118
119        let a = Member{name: "Alex", age: "18"};
120        let b = a;
121
122        let a = Member{name: "Alex".to_string(), age: "18"};
123        let b = a;
124    }
125    ```
126*/
127pub fn custom_types() {
128    println!(" Copy 和 Move 语义: 自定义类型实现 Copy 的一些情况 ");
129}
130
131/**
132    ### Rust 语义:Move 语义 与 Copy 语义
133
134    - 理解 Copy:Clone  https://doc.rust-lang.org/std/marker/trait.Copy.html
135
136
137    ```
138    struct A;
139
140    // 没用,自己实现Copy和Clone无法改变编译器默认行为
141    impl Clone for A {
142        fn clone(&self) -> Self {
143            println!("from Custom Copy: Clone");
144            *self
145        }
146    }
147
148    impl Copy for A {}
149
150
151    fn main(){
152        let a = A;
153        let b = a;
154    }
155
156    ```
157*/
158pub fn understand_copy_clone() {
159    println!(" 理解按位复制 : Copy ");
160}
161
162/**
163    ### Rust 语义:Move 语义 与 Copy 语义
164
165    - 理解 按位复制
166
167    ```
168    #[derive(Copy, Clone)]
169    struct A(i8, i32);
170    fn main() {
171        let a = A(1, 2);
172        let b = a; // 按位复制,复制后,b和a完全相同,包括内存对齐填充的padding部分。
173        let c = A(a.0, a.1); // 逐成员复制,非按位复制,c和a的padding部分不一定相同。
174    }
175
176    ```
177
178    示例二:
179
180    ```rust
181    #[derive(Debug, Copy, Clone)]
182    struct A {
183        a: u16,
184        b: u8,
185        c: bool,
186    }
187
188    fn main() {
189        let a = unsound_a();
190        // 尝试将 Some(a) 改为 a
191        let some_a = Some(a);
192
193        println!("a: {:#?}", a);
194        println!("some_a: {:#?}", some_a);
195    }
196
197
198    fn unsound_a() -> A {
199        #[derive(Debug, Copy, Clone)]
200        struct B {
201            a: u16,
202            b: u8,
203            c: u8,
204        }
205        // 依次修改 c 的值为 0,1,2 打印输出结果
206        let b = B { a: 1, b: 1, c: 1 };
207        unsafe {*(&b as *const B as *const A) }
208    }
209    ```
210
211    示例三:
212
213    ```rust
214    #![allow(unused_variables)]
215
216    use std::{ptr, mem};
217
218    fn main() {
219        let mut d = String::from("cccc");
220        let d_len = d.len();
221        // {
222            let mut c = String::with_capacity(d_len);
223
224            unsafe {
225                ptr::copy(&d, &mut c, 1);
226            };
227            println!("{:?}", c.as_ptr());
228            // unsafe {
229            //     ptr::drop_in_place(c.as_mut_ptr());
230            // }
231            // 注掉 drop,会产生double free,
232            // 但是不注掉 drop,会产生无效指针
233            mem::drop(c);
234        // }
235
236        println!("{:?}", d.as_ptr());
237        d.push_str("c");
238        println!("{}", d);
239    }
240    ```
241
242    示例四: Copy 不一定只在栈上进行
243
244    ```rust
245    use std::cell::RefCell;
246
247    fn main() {
248        let a = Box::new(RefCell::new(1));
249        let b = Box::new(RefCell::new(2));
250        *b.borrow_mut() = *a.borrow();
251        println!("b = {}", b.borrow());
252    }
253    ```
254*/
255pub fn understand_copy() {
256    println!(" 理解按位复制 : Copy ");
257}
258
259/**
260
261    示例1: Box<T> 实现 DereMove
262
263    ```rust
264    fn main(){
265        let s = Box::new("hello".to_string());
266        println!("{:p}", &s);
267        println!("{:p}", s.as_ptr());
268        // DerefMove
269        let s2 = *s;
270        // println!("{:p}", s.as_ptr()); // Moved s
271        println!("{:p}", s2.as_ptr());
272    }
273    ```
274
275    示例二:Arc 无法 DerefMove
276
277    https://doc.rust-lang.org/std/sync/struct.Arc.html
278
279
280
281    ```rust
282    use std::sync::Arc;
283
284    fn main(){
285        let s = Arc::new("hello".to_string());
286        println!("{:p}", &s);
287        println!("{:p}", s.as_ptr());
288        // DerefMove Error : cannot move out of an `Arc`
289        let s2 = *s;
290        // println!("{:p}", s.as_ptr()); // Moved s
291        println!("{:p}", s2.as_ptr());
292    }
293    ```
294
295*/
296pub fn understand_move() {
297    println!(" 理解 Move 语义: 解引用Move ");
298}
299
300/**
301    语义层面来理解 Clone :显式的clone方法调用同一种语义下的两种实现
302    1. String 等 引用类型的 Clone
303    2. Rc/Arc 类型的 Clone
304*/
305pub fn understand_clone() {
306    println!(" 理解 Move 语义: 解引用Move ");
307}
308
309/**
310
311    示例1: Move 的本质:drop 标记
312
313    ```rust
314    fn main(){
315        // impl Copy for i32
316        let mut a = "42".to_string();
317        let b = a; // drop(a);
318
319        a = "32".to_string();
320        println!("{:?}", a);
321    }
322    ```
323
324    示例二:Drop 析构函数
325
326
327    ```rust
328    struct PrintDrop(&'static str);
329    impl Drop for PrintDrop {
330        fn drop(&mut self) {
331            println!("Dropping {}", self.0)
332        }
333    }
334    fn main() {
335        let x = PrintDrop("x");
336        let y = PrintDrop("y");
337    }
338    ```
339
340    元组:
341
342    ```rust
343    struct PrintDrop(&'static str);
344        impl Drop for PrintDrop {
345            fn drop(&mut self) {
346                println!("Dropping {}", self.0)
347        }
348    }
349    fn main() {
350        let tup1 = (PrintDrop("a"), PrintDrop("b"), PrintDrop("c"));
351        let tup2 = (PrintDrop("x"), PrintDrop("y"), PrintDrop("z"));
352    }
353    ```
354
355    带panic的元组:
356
357    ```rust
358    struct PrintDrop(&'static str);
359    impl Drop for PrintDrop {
360        fn drop(&mut self) {
361            println!("Dropping {}", self.0)
362    }
363    }
364    fn main() {
365        let tup1 = (PrintDrop("a"), PrintDrop("b"), PrintDrop("c"));
366        let tup2 = (PrintDrop("x"), PrintDrop("y"), panic!());
367    }
368
369    ```
370
371    结构体:
372
373    ```rust
374    struct PrintDrop(&'static str);
375
376    impl Drop for PrintDrop {
377        fn drop(&mut self) {
378            println!("Dropping {}", self.0)
379        }
380    }
381
382    struct Foo {
383        bar: PrintDrop,
384        baz: PrintDrop,
385    }
386
387    impl Drop for Foo {
388        fn drop(&mut self) {
389            println!("Dropping Foo")
390        }
391    }
392
393    fn main() {
394        let foo = Foo {
395            bar: PrintDrop("bar"),
396            baz: PrintDrop("baz"),
397        };
398    }
399    ```
400
401    闭包:
402
403    ```
404    struct PrintDrop(&'static str);
405    impl Drop for PrintDrop {
406        fn drop(&mut self) {
407            println!("Dropping {}", self.0)
408        }
409    }
410    fn main() {
411        let z = PrintDrop("z");
412        let x = PrintDrop("x");
413        let y = PrintDrop("y");
414        let closure = move || { y; z; x; };
415    }
416    ```
417
418    闭包修改变量:
419
420    ```
421    struct PrintDrop(&'static str);
422    impl Drop for PrintDrop {
423        fn drop(&mut self) {
424            println!("Dropping {}", self.0)
425        }
426    }
427    fn main() {
428        let y = PrintDrop("y");
429        let x = PrintDrop("x");
430        let z = PrintDrop("z");
431        let closure = move || {
432            { let z_ref = &z; }
433            x; y; z;
434        };
435    }
436    ```
437
438    示例三: 所有权 forget/ ManuallyDrop
439
440    ```rust
441    // https://doc.rust-lang.org/src/alloc/sync.rs.html#319
442    impl<T> Arc<T> {
443        pub fn new(data: T) -> Arc<T> {
444            // Start the weak pointer count as 1 which is the weak pointer that's
445            // held by all the strong pointers (kinda), see std/rc.rs for more info
446            let x: Box<_> = box ArcInner {
447                strong: atomic::AtomicUsize::new(1),
448                weak: atomic::AtomicUsize::new(1),
449                data,
450            };
451            // ManuallyDrop
452            Self::from_inner(Box::leak(x).into())
453        }
454
455        // ...
456    }
457
458    impl<T> Weak<T> {
459        pub fn into_raw(self) -> *const T {
460            let result = self.as_ptr();
461            mem::forget(self);
462            result
463        }
464    }
465    ```
466
467*/
468pub fn understand_drop() {
469    println!(" 理解 Drop ");
470}