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);
    }
}
相关推荐
渣渣盟2 分钟前
JavaScript核心概念全解析
开发语言·javascript·es6
我的ID配享太庙呀15 分钟前
Django 科普介绍:从入门到了解其核心魅力
数据库·后端·python·mysql·django·sqlite
java叶新东老师1 小时前
goland编写go语言导入自定义包出现: package xxx is not in GOROOT (/xxx/xxx) 的解决方案
开发语言·后端·golang
檀越剑指大厂1 小时前
【Python系列】Flask 应用中的主动垃圾回收
开发语言·python·flask
檀越剑指大厂1 小时前
【Python系列】使用 memory_profiler 诊断 Flask 应用内存问题
开发语言·python·flask
笠码1 小时前
JVM Java虚拟机
java·开发语言·jvm·垃圾回收
fqbqrr2 小时前
2507rust,rust写驱动
rust
橙小花2 小时前
C语言:指针、变量指针与指针变量、数组指针与指针数组
c语言·开发语言
Cyanto2 小时前
MyBatis-Plus高效开发实战
java·开发语言·数据库
艾莉丝努力练剑2 小时前
【LeetCode&数据结构】二叉树的应用(二)——二叉树的前序遍历问题、二叉树的中序遍历问题、二叉树的后序遍历问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表