rust 智能指针

news/2024/11/8 22:47:17/

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!");// 获取引用计数为 1println!("strong_count: {}", Rc::strong_count(&str));// 创建一个新的所有者let str2 = Rc::clone(&str);// 获取引用计数为 2println!("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:

  1. 当你需要在不可变引用之间修改值时;

  2. 当你不能使用 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 类型。


http://www.ppmy.cn/news/85153.html

相关文章

双轮平衡车实现自平衡功能

1. 功能说明 在双轮小车上安装一个六轴陀螺仪传感器&#xff0c;本文示例将实现双轮小车自主平衡功能。 2. 电子硬件 在这个示例中&#xff0c;我们采用了以下硬件&#xff0c;请大家参考&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino Uno&#xff09; 扩展板 Big…

方正书版10.0快捷键

方正书版10.0快捷键 一、字符工具条快捷键 1、注解括弧对 ctrlshift[ 2、上标 ctrlshiftI 3、下标 ctrlshiftM 4、数学态切换符 ctrlshift; 5、转字体符 ctrlshift’ 6、页码目录替换符 ctrlshift? 7、盒组括弧 ctrlshift] 8、盘外符括弧 ctrlshift( 9、转义…

一个非系统工程师所关心的——Android开机流程

一、Loader层 1. Boot ROM: 上电后&#xff0c;BootRom会被激活&#xff0c;引导芯片代码开始从预定义的地方&#xff08;固化在ROM&#xff09;开始执行&#xff0c;然后加载引导程序到RAM。 2. Boot Loader引导程序 Android是基于Linux系统的&#xff0c;它没有BIO…

【Axure教程】通过文本框维护下拉列表选项

下拉列表&#xff08;Dropdown List&#xff09;是一种常见的用户界面元素&#xff0c;用于提供一组选项供用户选择。它通常以一个展开的列表形式出现&#xff0c;用户可以点击或选择列表中的一个选项。一般来说&#xff0c;他的选项值是由系统代码组成的&#xff0c;所以一般是…

JAVA LIST 根据对象元素去重

应用场景&#xff1a;在开发中过程中 会存在根据List集合中的对象一个或者多个元素进行去重 1&#xff1a;根据List集合中的对象一个元素进行去重 List<PurchaseHead> organizationPurchaseHeadList purchaseHeadList.stream().collect(Collectors.collectingAndThe…

uniapp前端图片布局时z-index出现的几个问题

目录 图片的z-index是怎么看的 一些规则: 图片没有z-index吗&#xff1f; 图片会优先覆盖其他元素吗&#xff1f; z-index失效 static elative、absolute或fixed的元素 元素的z-index覆盖子元素吗 图片的z-index是怎么看的 z-index属性用于控制元素的堆叠顺序,它只对定位…

进程控制

目录 进程创建 fork函数 写时拷贝 进程终止 进程退出场景 进程常见退出方法 进程等待 进程等待的必要性 进程等待的方法 wait方法 waitpid方法 获取子进程status 等待行为options 进程替换 各类程序替换函数的使用 命名理解 execl函数 execv函数 execlp函数…

利用PaddleOCR识别增值税发票平台验证码(开箱即用)

前言:全国增值税发票查验平台验证码没什么好说的,根据指定的颜色识别验证码中的文字,图片如下 下面直接讲解利用paddleocr识别的思路,为什么使用paddleocr,因为paddle中集成了较好的ocr文字识别模型,开箱即用即可,废话不多说,剑指主题,识别思路步骤如下 步骤如下 1、…