您现在的位置是:首页 >其他 >rust 智能指针网站首页其他
rust 智能指针
Rust中基本数据类型(如整数、浮点数、布尔值等)通常存储在栈上。而动态分配的数据,如Box<T>和Vec<T>等,存储在堆上。
Box 智能指针
Rust 中 Box 是一种智能指针类型,通常用于将值放置在堆上而不是栈上。在 Rust 中,由于所有值的默认生命周期都在当前作用域结束时结束,因此在情况需要延长对象的生命周期时,可以使用 Box 来将对象存储在堆上,以便在它们的所有权结束之前对它们进行访问。
struct User {
    name: String,
    age: i32,
}
fn main() {
    // 创建一个 User 对象,并将其存储在 Box 智能指针中
    let user = Box::new(User {
        name: "test".to_string(),
        age: 18,
    });
    // 通过解引用运算符来访问结构体对象的字段
    println!("name = {}", (*user).name);
    println!("age = {}", (*user).age);
    // 创建一个字符串对象,并将其存储在 Box 智能指针中
    let str = Box::new(String::from("Hello, World!"));
    // 通过解引用运算符来访问字符串对象中的字符
    println!("Character at index 7 = {}", (*str).chars().nth(7).unwrap());
}
Rc 智能指针
Rust 中的 Rc 类型是一个引用计数智能指针,它允许多个所有者共享相同的数据。每次创建一个 Rc 实例时,都会增加一个引用计数,并在所有者之间共享这个计数。当没有所有者时,引用计数将递减,一旦它达到零,数据将被释放。
use std::rc::Rc;
fn main() {
    let str = Rc::new("Hello, world!");
    // 获取引用计数为 1
    println!("strong_count: {}", Rc::strong_count(&str));
    // 创建一个新的所有者
    let str2 = Rc::clone(&str);
    // 获取引用计数为 2
    println!("strong_count: {}", Rc::strong_count(&str));
    println!("strong_count: {}", Rc::strong_count(&str2));
}Arc 智能指针
Rust 中的 Arc 类型是一个原子引用计数,在多线程环境中,Rc 无法安全地使用,因为它的引用计数无法保证并发安全。Arc 提供了高效而安全的共享所有权机制,通过使用原子变量来保证线程安全。Arc 是一种非常有用的智能指针。它通过使用 clone 方法并通过原子方式增加引用计数来创建新的所有权证书,从而允许在多个线程中共享数据。
use std::sync::Arc;
use std::thread;
fn main() {
    let data = Arc::new(vec![1, 2, 3, 4, 5]);
    let handle = thread::spawn(move || {
        //克隆了一份到线程内部
        let local_data = data.clone();
        println!("local_data: {:?}", local_data);
    });
    handle.join().unwrap();
}Cell 智能指针
Rust 中的 Cell 类型是一个原子可变容器,它允许我们持有一个不可变对象,并提供了对其中一个字段进行可变访问的能力。它常被用于资源共享或状态修改的小场景中。
use std::cell::Cell;
struct Point {
    x: i32,
    y: Cell<i32>,
}
fn main() {
    let point = Point { x: 5, y: Cell::new(10) };
    let old_y = point.y.get();
    point.y.set(20);
    let new_y = point.y.get();
    println!("Old y was {}, new y is {}", old_y, new_y);
}RefCell 智能指针
Rust 中的 RefCell 类型是一个智能指针,它提供了内部可变性(mutability),允许我们在不可变引用之间修改值。但是,与 Cell 不同的是,RefCell 会在运行时进行借用检查来保证数据的安全性。
主要在以下两种情况下使用 RefCell:
-  当你需要在不可变引用之间修改值时; 
-  当你不能使用 Rc,但仍需要共享所有权的时候。 
use std::cell::RefCell;
fn main() {
    //RefCell提供内部可变性
    let cell = RefCell::new(10);
    {
        // 运行时会检查借用规则,所以这里必须加大括号
        // 将可写借用跟后面的只读借用隔离开来
        let mut mut_ref = cell.borrow_mut();
        *mut_ref += 1;
    }
    println!("{}", cell.borrow()); //11
}
RefCell相比Cell,内部维护了一个包装对象的引用计数,当通过 RefCell.borrow 获取一个共享引用时,内部引用计数加一,当获取的引用离开作用域时,内部引用计数减一,当RefCell.borrow_mut 获取一个可变引用时,首先检测引用计数是否为 0,如果为 0,正常返回,如果不为 0,直接 panic,其实 RefCell.borrow 时也会做类似的检测,当已经获取了可变引用也是直接 panic, 当然为了避免 panic,可以用 RefCell.try_borrow 和 RefCell.try_borrow_mut 来获取一个 Result 类型。
 
            




 U8W/U8W-Mini使用与常见问题解决
U8W/U8W-Mini使用与常见问题解决 QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。... stm32使用HAL库配置串口中断收发数据(保姆级教程)
stm32使用HAL库配置串口中断收发数据(保姆级教程) 分享几个国内免费的ChatGPT镜像网址(亲测有效)
分享几个国内免费的ChatGPT镜像网址(亲测有效) Allegro16.6差分等长设置及走线总结
Allegro16.6差分等长设置及走线总结