当前位置: 首页 > news >正文

智能指针完全指南

Rust 智能指针完全指南

简介

智能指针是一类数据结构,它们的行为类似于指针,但拥有额外的元数据和功能。Rust 标准库提供了多种智能指针,用于不同的场景。

主要智能指针类型

  1. Box<T> - 堆上分配
  2. Rc<T> - 引用计数
  3. Arc<T> - 原子引用计数
  4. RefCell<T> - 内部可变性
  5. Mutex<T> - 互斥锁

Box - 堆分配

Box 是最简单的智能指针,用于在堆上分配值。

fn box_examples() {// 基本用法let b = Box::new(5);println!("b = {}", b);// 递归类型必须使用 Box#[derive(Debug)]enum List {Cons(i32, Box<List>),Nil,}use List::{Cons, Nil};let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));println!("列表: {:?}", list);
}

复杂案例:实现一个二叉搜索树

使用 Box 实现一个功能完整的二叉搜索树:

use std::cmp::Ordering;#[derive(Debug)]
struct TreeNode<T> {value: T,left: Option<Box<TreeNode<T>>>,right: Option<Box<TreeNode<T>>>,
}struct BinarySearchTree<T> {root: Option<Box<TreeNode<T>>>,size: usize,
}impl<T: Ord + std::fmt::Debug> BinarySearchTree<T> {fn new() -> Self {BinarySearchTree {root: None,size: 0,}}fn insert(&mut self, value: T) {self.size += 1;self.root = Self::insert_node(self.root.take(), value);}fn insert_node(node: Option<Box<TreeNode<T>>>, value: T) -> Option<Box<TreeNode<T>>> {match node {None => Some(Box::new(TreeNode {value,left: None,right: None,})),Some(mut n) => {match value.cmp(&n.value) {Ordering::Less => {n.left = Self::insert_node(n.left.take(), value);}Ordering::Greater => {n.right = Self::insert_node(n.right.take(), value);}Ordering::Equal => {// 值已存在,不插入}}Some(n)}}}fn contains(&self, value: &T) -> bool {Self::contains_node(&self.root, value)}fn contains_node(node: &Option<Box<TreeNode<T>>>, value: &T) -> bool {match node {None => false,Some(n) => {match value.cmp(&n.value) {Ordering::Equal => true,Ordering::Less => Self::contains_node(&n.left, value),Ordering::Greater => Self::contains_node(&n.right, value),}}}}fn inorder_traversal(&self) -> Vec<&T> {let mut result = Vec::new();Self::inorder(&self.root, &mut result);result}fn inorder(node: &Option<Box<TreeNode<T>>>, result: &mut Vec<&T>) {if let Some(n) = node {Self::inorder(&n.left, result);result.push(&n.value);Self::inorder(&n.right, result);}}fn height(&self) -> usize {Self::calculate_height(&self.root)}fn calculate_height(node: &Option<Box<TreeNode<T>>>) -> usize {match node {None => 0,Some(n) => {let left_height = Self::calculate_height(&n.left);let right_height = Self::calculate_height(&n.right);1 + left_height.max(right_height)}}}fn len(&self) -> usize {self.size}
}fn demonstrate_bst() {let mut bst = BinarySearchTree::new();// 插入数据let values = vec![5, 3, 7, 1, 9, 4, 6];for val in values {bst.insert(val);}println!("树的大小: {}", bst.len());println!("树的高度: {}", bst.height());// 检查包含println!("包含 5? {}", bst.contains(&5));println!("包含 10? {}", bst.contains(&10));// 中序遍历(有序输出)let sorted = bst.inorder_traversal();println!("中序遍历: {:?}", sorted);
}// Rc<T> - 引用计数智能指针
use std::rc::Rc;fn rc_examples() {let data = Rc::new(vec![1, 2, 3, 4, 5]);println!("初始引用计数: {}", Rc::strong_count(&data));{let data2 = Rc::clone(&data);let data3 = Rc::clone(&data);println!("克隆后引用计数: {}", Rc::strong_count(&data));println!("data2: {:?}", data2);println!("data3: {:?}", data3);}println!("作用域结束后引用计数: {}", Rc::strong_count(&data));
}// 使用 Rc 实现图结构
use std::cell::RefCell;#[derive(Debug)]
struct GraphNode {id: usize,neighbors: RefCell<Vec<Rc<GraphNode>>>,
}impl GraphNode {fn new(id: usize) -> Rc<Self> {Rc::new(GraphNode {id,neighbors: RefCell::new(Vec::new()),})}fn add_neighbor(&self, neighbor: Rc<GraphNode>) {self.neighbors.borrow_mut().push(neighbor);}fn neighbors(&self) -> Vec<usize> {self.neighbors.borrow().iter().map(|n| n.id).collect()}
}fn demonstrate_graph() {let node1 = GraphNode::new(1);let node2 = GraphNode::new(2);let node3 = GraphNode::new(3);// 建立连接node1.add_neighbor(Rc::clone(&node2));node1.add_neighbor(Rc::clone(&node3));node2.add_neighbor(Rc::clone(&node3));println!("节点 1 的邻居: {:?}", node1.neighbors());println!("节点 2 的邻居: {:?}", node2.neighbors());println!("节点 1 的引用计数: {}", Rc::strong_count(&node1));
}// RefCell<T> - 内部可变性
struct Counter {count: RefCell<i32>,
}impl Counter {fn new() -> Self {Counter {count: RefCell::new(0),}}fn increment(&self) {*self.count.borrow_mut() += 1;}fn get(&self) -> i32 {*self.count.borrow()}fn reset(&self) {*self.count.borrow_mut() = 0;}
}fn demonstrate_refcell() {let counter = Counter::new();counter.increment();counter.increment();counter.increment();println!("计数: {}", counter.get());counter.reset();println!("重置后: {}", counter.get());
}// 组合 Rc 和 RefCell 实现共享可变状态
struct SharedList<T> {items: Rc<RefCell<Vec<T>>>,
}impl<T: Clone> SharedList<T> {fn new() -> Self {SharedList {items: Rc::new(RefCell::new(Vec::new())),}}fn add(&self, item: T) {self.items.borrow_mut().push(item);}fn clone_list(&self) -> SharedList<T> {SharedList {items: Rc::clone(&self.items),}}fn get_all(&self) -> Vec<T> {self.items.borrow().clone()}fn len(&self) -> usize {self.items.borrow().len()}
}fn demonstrate_shared_list() {let list1 = SharedList::new();let list2 = list1.clone_list();list1.add("Rust");list2.add("is");list1.add("awesome");println!("列表 1: {:?}", list1.get_all());println!("列表 2: {:?}", list2.get_all());println!("两者共享同一数据!");
}fn main() {println!("=== Box 示例 ===");box_examples();println!("\n=== 二叉搜索树 ===");demonstrate_bst();println!("\n=== Rc 示例 ===");rc_examples();println!("\n=== 图结构 ===");demonstrate_graph();println!("\n=== RefCell 示例 ===");demonstrate_refcell();println!("\n=== 共享列表 ===");demonstrate_shared_list();
}

智能指针对比

类型所有权可变性线程安全
Box独占取决于 mut
Rc共享不可变
Arc共享不可变
RefCell独占内部可变
Mutex共享内部可变

总结

智能指针是 Rust 中管理内存和实现复杂数据结构的强大工具。选择合适的智能指针可以让代码更加安全和高效。

http://www.dtcms.com/a/536547.html

相关文章:

  • 数字阵列雷达(三)——系统工作原理(接收)
  • linux动态库加载方式:dlopen和直接链接.so库的区别?
  • 可克达拉市建设局网站呼和浩特做网站的地方
  • 插入排序:扑克牌式的排序算法!
  • 如何实现简单的HTTP代理服务器
  • vscode断点使用
  • 做自己网站做站长网站模板对seo的影响
  • Rust中的异常处理方式
  • ETCD 学习使用
  • 新能源汽车故障诊断与排除虚拟实训软件——赋能职业教育新工具
  • 自用提示词02 || Prompt Engineering || RAG数据切分 || 作用:通过LLM将文档切分成chunks
  • 网站开发实战作业答案成功网站案例有哪些
  • 对电子商务网站建设与管理的理解我想做个网站推广怎么做
  • 青少年机器人技术(六级)等级考试试卷-实操题(2025年9月)
  • Spring Boot核心知识点全解析
  • 如何在Qt QML中定义枚举浅谈
  • 6 mysql源码中的查询逻辑
  • 网站a记录的是做cname网页设计欣赏分析
  • Optuna 黑科技自动化超参数优化框架详解
  • 江西省第二届职业技能大赛网络安全赛题 应急响应
  • 网站制作哪家好又便宜东莞建设企业网站
  • 提高命令行运行效率-正则 表达式
  • wordpress自适应建站汽车网有哪些网站大全
  • 爱站网是干嘛的怎么做废品收购网站
  • 如何从 GitHub 大仓库中只下载指定目录
  • LeetCode 22. 括号生成
  • IHR 2025 | 移远通信携Robrain AI解决方案亮相,开启机器人全感官交互新纪元
  • 淘宝客做网站自动更新写wordpress插件吗
  • 金融--------
  • 视频号AI口播:中老年赛道发力