Rust中,Box,Rc,RefCell使用依据,案例

选择 Box<T>、RC<T>、RefCell<T>的依据:

|----------|-----------------|--------------|-----------------|
| | box | Rc | RefCell |
| 统一数据的所有者 | 一个 | 多个 | 一个 |
| 可变性、借用检查 | 可变、不可变借用(编译时检查) | 不可变借用(编译时检查) | 可变、不可变借用(运行时检查) |
| 是否会开辟堆空间 | 是 | 是 | 否 |

案例一、Box实现链表,链表循环

rust 复制代码
#[derive(Debug)]
pub enum Node {
    Value(i32, Box<Node>),
    Nil,
}

pub fn test1() {
    let list = Box::new(Node::Value(
        1,
        Box::new(Node::Value(
            2,
            Box::new(Node::Value(3, Box::new(Node::Nil))),
        )),
    ));

    // 循环列表方法一
    // let mut current = list;
    // while let Node::Value(val, next) = *current {
    //     println!("Value: {}", val);
    //     current = next;
    // }

    // 循环列表方法二
    let mut current = list;
    loop {
        match *current {
            Node::Value(val, next) => {
                println!("Value: {}", val);
                current = next;
            }
            Node::Nil => break,
        }
    }

    // 定义了一个长度10,全是0的数组
    let a = Box::new([0; 10]);
    let b = &a;
    let c = &a;
    let d = &a;
    println!("{:?},{:?},{:?},{:?}", a, b, c, d);
}

案例二、分别使用Rc、Box实现链表

rust 复制代码
use std::rc::Rc;

// Rc
#[derive(Debug)]
enum Node {
    Cons(i32, Rc<Node>),
    Nil,
}

pub fn test2() {
    let list = Rc::new(Node::Cons(
        1,
        Rc::new(Node::Cons(2, Rc::new(Node::Cons(3, Rc::new(Node::Nil))))),
    ));

    let list2 = Rc::new(Node::Cons(0, Rc::new(Node::Cons(1, Rc::clone(&list)))));

    let list3 = Rc::new(Node::Cons(4, Rc::new(Node::Nil)));

    println!("{:#?}, {:#?}, {:#?}", list, list2, list3);
}

// Box
#[derive(Debug)]
enum Node2<'a> {
    Cons(i32, &'a Box<Node2<'a>>),
    Nil,
}

pub fn test22() {
    let null = Box::new(Node2::Nil);
    let n5 = Box::new(Node2::Cons(1, &null));
    let n4 = Box::new(Node2::Cons(1, &n5));
    let n3 = Box::new(Node2::Cons(1, &n4));
    let n2 = Box::new(Node2::Cons(1, &n3));
    let n1 = Box::new(Node2::Cons(1, &n2));
    let list = Box::new(Node2::Cons(4, &n1));
    println!("{:#?}", list);
}

案例三、使用Box,Rc,RefCell实现链表循环添加,遍历

rust 复制代码
// 二级指针的链表,一级就够了,box可以删掉,存储过多的变量地址,会降低运行效率。
use std::{cell::RefCell, rc::Rc};

#[derive(Debug)]
enum Node {
    Value(i32, Rc<RefCell<Box<Node>>>),
    Nil,
}

pub fn test3() {
    let list = Rc::new(RefCell::new(Box::new(Node::Nil)));
    let mut tmp = Rc::clone(&list);

    for i in 1..=10 {
        let newNode = Rc::new(RefCell::new(Box::new(Node::Nil)));
        *tmp.borrow_mut() = Box::new(Node::Value(i, Rc::clone(&newNode)));
        tmp = newNode;
    }

    let mut tmp = Rc::clone(&list);

    while let Node::Value(num, next) = &**(tmp.clone().borrow()) {
        println!("{:?}", num);
        tmp = Rc::clone(&next);
    }
}
相关推荐
2501_945424802 分钟前
模板代码版本兼容
开发语言·c++·算法
工边页字3 分钟前
AI公司面试100%加分的话题:如何做 API成本预算
前端·后端·面试
sunwenjian8863 分钟前
Spring Boot 整合 Druid 并开启监控
java·spring boot·后端
m0_518019485 分钟前
C++中的委托构造函数
开发语言·c++·算法
Java编程爱好者6 分钟前
阿里面试官:什么才是可工程化落地的RAG项目
后端
m0_743470377 分钟前
高性能计算框架实现
开发语言·c++·算法
weixin_307779137 分钟前
2025年中国研究生数学建模竞赛A题:通用神经网络处理器下的核内调度问题——解决方案与实现
开发语言·人工智能·python·数学建模·性能优化
焦糖玛奇朵婷8 分钟前
盲盒小程序开发|解锁开箱新体验[特殊字符]
大数据·开发语言·程序人生·小程序·软件需求
1104.北光c°8 分钟前
基于Canal + Kafka的高可用关注系统:一主多从关系链
java·开发语言·笔记·分布式·程序人生·kafka·一主多从
Mem0rin10 分钟前
[Java]异常及其处理
java·开发语言