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);
    }
}
相关推荐
StrongerIrene几秒前
rs build 的process.env的值undefined解决方案
开发语言·javascript·ecmascript
风逸hhh12 分钟前
python打卡day58@浙大疏锦行
开发语言·python
Q_9709563925 分钟前
java+vue+SpringBoo足球社区管理系统(程序+数据库+报告+部署教程+答辩指导)
java·开发语言·数据库
程序员爱钓鱼33 分钟前
Go语言中的反射机制 — 元编程技巧与注意事项
前端·后端·go
为了更好的明天而战1 小时前
Java 中的 ArrayList 和 LinkedList 区别详解(源码级理解)
java·开发语言
JosieBook1 小时前
【Java编程动手学】Java中的数组与集合
java·开发语言·python
qq_589568101 小时前
element-plus按需自动导入的配置 以及icon图标不显示的问题解决
开发语言·javascript·ecmascript
lsx2024061 小时前
SQLite Select 语句详解
开发语言
Dovis(誓平步青云)2 小时前
基于探索C++特殊容器类型:容器适配器+底层实现原理
开发语言·c++·queue·适配器·stack
R-sz2 小时前
java流式计算 获取全量树形数据,非懒加载树,递归找儿
java·开发语言·windows