Rust 智能指针
名称 | 简介 | 强项 | 弱项 |
---|
Raw Pointer | *mut T 和 *const T,自由基,闪电般块,极其 Unsafe | 速度、与外界交互 | Unsafe |
Box<T> | 可把任何东西都放在Box里。可接受几乎任何类型的长期存储。新的安全编程时代的主力军。 | 将值集中存储在 Heap | 大小增加 |
Rc<T> | 是Rust的能干而吝啬的簿记员。它知道谁借了什么,何时借了什么 | 对值的共享访问 | 大小增加;运行时成本;线程不安全 |
Arc<T> | 是Rust的大使。它可以跨线程共享值,保证这些值不会相互干扰 | 对值的共享访问;线程安全 | 大小增加;运行时成本 |
Cell<T> | 变态专家,具有改变不可变值的能力 | 内部可变性 | 大小增加;性能 |
RefCell<T> | 对不可变引用执行改变,但有代价 | 内部可变性;可与仅接受不可变引用的Rc、Arc嵌套使用 | 大小增加;运行时成本;缺乏编译时保障 |
Cow<T> | 封闭并提供对借用数据的不可变访问,并在需要修改或所有权时延迟克隆数据 | 当只是只读访问时避免写入 | 大小可能会增大 |
String | 可处理可变长度的文本,展示了如何构建安全的抽象 | 动态按需增长;在运行时保证正确编码 | 过度分配内存大小 |
Vec<T> | 程序最常用的存储系统;它在创建和销毁值时保持数据有序 | 动态按需增长 | 过度分配内存大小 |
RawVec<T> | 是Vec<T> 和其它动态大小类型的基石;知道如何按需给你的数据提供一个家 | 动态按需增长;与内存分配器一起配合寻找空间 | 不直接适用于您的代码 |
Unique<T> | 作为值的唯一所有者,可保证拥有完全控制权 | 需要独占值的类型(如 String)的基础 | 不适合直接用于应用程序代码 |
Shared<T> | 分享所有权很难,但他使生活更轻松 | 共享所有权;可以将内存与T的宽度对齐,即使是空的时候 | 不适合直接用于应用程序代码 |
use std::{cell::Cell, rc::Rc, str::FromStr, sync::{atomic::{AtomicUsize, Ordering}, Arc}, thread, time::Duration};fn main() {println!("1. 引用是一种指针");let a:[u8;10] = [1,2,3,4,5,6,7,8,9,10]; let a1 = &a; let a2 = &a1; println!("{:p} {:p} {:p}", &a[0], a1, a2); println!("2. unsafe中的 *mut T 是裸指针");let b = String::from_str("Hello").unwrap(); let b1 = b.as_ptr(); let b2 = b1 as *mut u8; println!("{:p} {:p} {:p}", &b, b1, b2);println!("3. Box<T> 将数据在堆heap上分配,返回指针");let mut c = Box::new(123); *c = 456;println!("{:p} {}", c, *c); println!("4. Rc<T> 实现多个实例对T的共享访问(只读),内部使用引用计数");let d = Rc::new(String::from("test counting"));println!("creating = {}", Rc::strong_count(&d)); let d1 = Rc::clone(&d);println!("clone = {}", Rc::strong_count(&d1)); {let d2 = Rc::clone(&d);println!("clone2 = {}", Rc::strong_count(&d2)); }println!("out of scope = {}", Rc::strong_count(&d)); println!("5. Arc<T> 类似Rc, 但是有lock机制,可以提供多线程并发安全(只读).");let e= Arc::new(vec![10,12,13]); let e1 = e.clone(); println!("{:p} {:p}", e, e1);arc_test1(); println!("6. Cell<T>/RefCell<T> 提供内部T可变性,用来解决&mut在struct的传染问题.");cell_test1(); println!("7. String 在处理可变长度字符串时,动态增长内存大小.");let mut f = String::from("123"); println!("String capacity: {}, len:{}, addr: {:p}", f.capacity(), f.len(), f.as_ptr());f = f + "qweqwrewteryrtuytiuyoiupio[pio[op]tyertwerwer"; println!("String capacity: {}, len:{}, addr: {:p}", f.capacity(), f.len(), f.as_ptr());println!("8. Vec<T> 内部按需阶梯增长内部空间,不是每次都一定新分配.");let mut e = vec![1,2,3]; println!("String capacity: {}, len:{}, addr: {:p}", e.capacity(), e.len(), e.as_ptr()); e.push(4);println!("String capacity: {}, len:{}, addr: {:p}", e.capacity(), e.len(), e.as_ptr()); e.push(5);println!("String capacity: {}, len:{}, addr: {:p}", e.capacity(), e.len(), e.as_ptr()); e.push(6);e.push(6);e.push(6);println!("String capacity: {}, len:{}, addr: {:p}", e.capacity(), e.len(), e.as_ptr()); }fn arc_test1(){let val = Arc::new(AtomicUsize::new(5));for i in 0..10 {let val = Arc::clone(&val);thread::spawn(move || {let v = val.fetch_add(1, Ordering::SeqCst); println!("{} {:?}", i, v+1);});}thread::sleep(Duration::from_secs(3));
}fn cell_test1(){struct Person{age: Cell<u32>,name: String,}let p = Person{age: Cell::new(31), name: "zhangsan".to_string()};p.age.set(40);println!("{} {}", p.age.get(), p.name);
}