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}