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);
    }
}
相关推荐
C+-C资深大佬13 分钟前
C++风格的命名转换
开发语言·c++
No0d1es16 分钟前
2025年粤港澳青少年信息学创新大赛 C++小学组复赛真题
开发语言·c++
点云SLAM19 分钟前
C++内存泄漏检测之手动记录法(Manual Memory Tracking)
开发语言·c++·策略模式·内存泄漏检测·c++实战·new / delete
码上成长24 分钟前
JavaScript 数组合并性能优化:扩展运算符 vs concat vs 循环 push
开发语言·javascript·ecmascript
打工的小王29 分钟前
java并发编程(三)CAS
java·开发语言
油丶酸萝卜别吃36 分钟前
Mapbox GL JS 表达式 (expression) 条件样式设置 完全指南
开发语言·javascript·ecmascript
飞Link36 分钟前
【Django】Django的静态文件相关配置与操作
后端·python·django
爱吃大芒果1 小时前
Flutter for OpenHarmony前置知识:Dart 语法核心知识点总结(下)
开发语言·flutter·dart
Ulyanov1 小时前
从桌面到云端:构建Web三维战场指挥系统
开发语言·前端·python·tkinter·pyvista·gui开发
星火开发设计1 小时前
C++ 函数定义与调用:程序模块化的第一步
java·开发语言·c++·学习·函数·知识