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);
    }
}
相关推荐
TNTLWT12 分钟前
Qt控件:交互控件
开发语言·qt
量化金策14 分钟前
震荡指标工具
开发语言
北漂老男孩16 分钟前
ChromeDriver进程泄漏问题分析与最佳实践解决方案
开发语言·爬虫
李迟21 分钟前
Golang实践录:在go中使用curl实现https请求
开发语言·golang·https
运维-大白同学1 小时前
go-数据库基本操作
开发语言·数据库·golang
动感光博2 小时前
Unity(URP渲染管线)的后处理、动画制作、虚拟相机(Virtual Camera)
开发语言·人工智能·计算机视觉·unity·c#·游戏引擎
蚰蜒螟2 小时前
深入解析JVM字节码解释器执行流程(OpenJDK 17源码实现)
开发语言·jvm·python
keke103 小时前
Java【14_2】接口(Comparable和Comparator)、内部类
java·开发语言
思茂信息3 小时前
CST软件对OPERA&CST软件联合仿真汽车无线充电站对人体的影响
c语言·开发语言·人工智能·matlab·汽车·软件构建
CN.LG3 小时前
Java 乘号来重复字符串的功能
java·开发语言