Rc与Box区别

Rust Rc(引用计数)方法详解 总结一下,Rust中的Rc提供了一种方便的共享所有权的机制,通过引用计数来跟踪值的使用情况。使用Rc时,需要注意循环引用的问题,因为Rc无法处理循环引用的情况,可能导致内存泄漏。它允许多个引用同时指向同一个值,通过计数器来跟踪当前有多少个引用指向该值,从而在引用计数为零时自动释放该值。除了上述方法之外,Rc还实现了Deref和Drop trait,使得可以像操作普通引用一样操作Rc指针。方法,通过Deref trait,我们可以直接在Rc指针上调用这个方法。方法获取当前引用计数,并打印输出。 阅读详情

咋一看觉得这两个概念差的很远,其实他们之间还是有联系的:

  • 相同点:
    他们都是在堆上分配资源,都只是保存了一个指向堆上的指针
  • 区别:
    • Box就是一个简单的指向堆的指针,并且指向堆的这个区域的指针只能有一个,owner lifetime结束就会释放堆上的资源
    • Rc增加了一个计数(准确来说是两个指针),可以多个指针指向堆的这个区域,等所有的引用者lifetime结束了才释放堆上的资源

下面的代码为了看起来清爽点删除了注释

1 这个是Rc的定义

struct RcBox<T: ?Sized> {
    strong: Cell<usize>,
    weak: Cell<usize>,
    value: T,
}

pub struct Rc<T: ?Sized> {
    _ptr: NonZero<*mut RcBox<T>>,
}

其中NonZero很简单,就是简单的包装了下T

pub struct NonZero<T: Zeroable>(T);

具体可以看:
http://doc.rust-lang.org/stable/src/alloc/rc.rs.html#172

2 Box定义如下:

pub struct Box<T>(Unique<T>);

http://doc.rust-lang.org/stable/src/alloc/boxed.rs.html#94

其中Unique定义如下:

pub struct Unique<T: ?Sized> {
    pointer: NonZero<*const T>,
    _marker: PhantomData<T>,
}

http://doc.rust-lang.org/stable/src/core/ptr.rs.html#513-521
Unique里的marker是不占用存储空间的,可以暂时忽略掉

3 具体的例子:

use std::rc::Rc;

#[derive(Debug)]
struct Foo(i32);


fn main(){
    let r:Rc<Foo>;
    let b:Box<Foo>;
    {
        let r1 = Rc::new(Foo(100));
        println!("r1:{:p}",&*r1);
        //clone计数
        r = r1.clone();
        //多处引用,都可以分别访问
        println!("r1:{:?}",r1);

        let b1 = Box::new(Foo(200));
        println!("b1:{:p},data:{}",&*b1,(*b1).0);
        //owner ship 转移了
        b = b1;
        //b1不能再访问
        //println!("{:?}",b1);
    }
    println!("{:?}",r);
    println!("r:{:p}",&*r);

    println!("{:?}",b);
    println!("b:{:p}",&*b);
}

Play地址:http://is.gd/rGBLaW
输出结果:

r1:0x7f621582d010
r1:Foo(100)
b1:0x7f6215823020,data:200
Foo(100)
r:0x7f621582d010
Foo(200)
b:0x7f6215823020

Box,Rc 都是在堆上分配的,那么都可以存在于定义它的范围之外。

  • Rc是通过引用计数的方式获得更长的lifetime,这儿r=r1.clone()就把堆上的对象的lifetime增加到了外层block对应的lifetime
  • Box通过转移owner ship的方式把b1传递给了b从而让Box指向的堆上的资源没有被释放。

在这种情况下都可以通过不同的方式实现lifetime的扩张,但还是有区别的:

  • Box方式转移了owner ship之后就不能再访问原来的b1了,也就是只能一个指针指向Box在堆上分配的资源
  • Rc通过增加引用计数的方式实现了lifetime的扩张,并且r1还是继续使用的
恋爱脑学Rust之Box与RC的对比 Rc的共享之爱Rc像阿丽的共享理念,多人共享访问,所有人都可以共同拥有心之花,并增加引用计数来管理。Box的唯一之爱Box像小明的独占信念,所有权单一,只能有一个唯一的持有者,不允许随意转让。这两种智能指针在 Rust 中适合不同的场景:当需要共享所有权时,Rc是理想选择,而当独占所有权是必要时,Box是最佳选择。Rust 的智能指针机制帮助阿丽和小明在自己的爱情中找到了平衡,使得心之花在不同场景中都绽放得美丽而安全。 阅读详情

相关推荐

[重学Rust]之智能指针

【Rust智能指针全解析】本文系统梳理Rust五大智能指针:Box(堆内存分配)、RefCell(运行时借用检查)、Rc/Arc(单/多线程引用计数)、Mutex(互斥锁)和RwLock(读写锁)。通过代码示例详解各自特性:Box实现堆栈分离;RefCell实现编译期不可变值的运行时可变借用;Rc/Arc管理共享所有权;Mutex保障线程独占访问;RwLock优化读多写少场景。特别对比Mutex与RwLock的适用场景,帮助开发者根据线程安全需求灵活选择。文章附带完整示例代码,适合Rust开发者深入理解所有

盹猫的博客 1521

Rust: Box 智能指针进阶 - Rc、RefCell、Weak

Rust: Box 智能指针进阶 - Rc、RefCell、Weak 文章目录Rust: Box 智能指针进阶 - Rc、RefCell、Weak正文1. Box 类型复习2. 自定义模拟 Box 类型3. 递归类型定义4. Box 进阶:Rc5. Box 进阶:RefCell6. 循环依赖 & Weak7. 结论其他资源参考连接完整代码示例 正文 1. Box 类型复习 Rust 内置类型: Box、Option、Result Box 为一种特别的引用类型,实际数据存储在堆上 Box 作为引用类

超悠閒的博客 2653

[DevExpress]GridControl拖拽行记录排序

DevExpress的GridControl拖拽行记录排序需求效果代码 需求 现在用户对按钮点击排序不满意了, 希望拖拽排序。 重载GridControl控件,对MouseMove、MouseDown、MouseUp事件修改一下。 效果 代码 using System; using System.Drawing; using System.Windows.Forms; using xiaoid.forms; using System.Data; using System.Collections.Gener

德仔 1561

rust学习——智能指针Rc

Rc/Arc是不可变引用,你无法修改它指向的值,只能进行读取,如果要修改,需要配合后面章节的内部可变性RefCell或互斥锁Mutex一旦最后一个拥有者消失,则资源会自动被回收,这个生命周期是在编译期就确定下来的Rc只能用于同一线程内部,想要用于线程之间的对象共享,你需要使用ArcRc是一个智能指针,实现了Deref特征,因此你无需先解开Rc指针,再使用里面的T,而是可以直接使用T,例如上例中的。

mirana的专栏 1380

用 MVC 框架把 ABAP 报表写成可扩展的应用(2)

本文介绍了一个基于MVC架构的SAP报表模板,解决了传统ABAP报表开发中的三个核心痛点: 选择屏幕校验逻辑分散问题 - 通过统一的选择屏幕控制器集中管理校验逻辑 在线与后台输出不一致问题 - 共享同一数据模型,通过不同控制器实现多样化展示 屏幕流转管理混乱问题 - 主控制器统一管理所有屏幕流程和事件 该模板采用分层架构: Model层专注数据获取和业务规则 Controller层管理流程和交互 View层负责展示逻辑 特别适用于需要同时支持交互式ALV展示和后台批处理输出的报表场景,通过标准化的扩展点设计

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 78

Linux Namespace隔离实战:dd/mkfs/mount/unshare构建终极沙箱

内存占用 | 512MB+ | **<10MB** | 50倍节省 || 启动时间 | 15-45秒 | **0.1-0.5秒** | 100倍加速 || 磁盘空间 | GB级 | **MB级** | 显著减少 || 系统调用性能 | 有损耗 | **原生速度** | 零损耗 |

Loving_enjoy的博客 398

彻底搞懂Rust智能指针:Box/Rc/Arc/RefCell应用场景全解析

你还在为Rust的内存管理头疼吗?面对Box、Rc、Arc和RefCell这些智能指针,是不是不知道该在什么时候用哪个?本文将通过实际场景和代码示例,帮你彻底搞懂这四种智能指针的核心用法,解决90%的ownership问题。读完本文你将能够:掌握每种智能指针的适用场景、避免常见的内存安全错误、写出更优雅的Rust代码。 ## 什么是智能指针 智能指针(Smart Pointer)是Rust中一...

gitblog_00278的博客 464

迟滞比较器原理及计算

为什么要用迟滞比较器 在讲迟滞比较器之前,我们先看一个案例。 在产品设计中常常需要用到电机,而电机在从运转到停止过程中需要泄放能量,这种能量大部分以电压的形式反馈回电源母线(Vbus)导致Vbus母线电压升高,特别是功率大又转速快的电机需要急刹时,产生的反馈电压更高,严重时可能导致母线上其他器件的损坏。 为了防止将电机反馈的能量泄放掉,我们需要设计一个电路来检测母线电压,当母线电压高于某一安全阈值时,打开MOSFET Q1将母线上的能量通过电阻R5以热的形式消耗掉。 假如用一般的比较器,设计如下: Vbu

sinat_15677011的博客 2万+

Rust 中的 Rc智能指针

Rust 中的 Rc智能指针 1 初识 Rc 先看个简单例子: use std::rc::Rc; fn main() { let x = Rc::new(123); println!("{:?}", x); } --------------------------------------------------- cargo run 123 这个与 Box 指针几乎一样,二者区别在于 clone() 的具体执行过程。 2 clone() 方法 看下面的例子: use std::rc::Rc

程序猿视角 1260

寄存器与计数器设计(Verilog)

always @(posedge Reset or posedge Clock)//请在括号中补充敏感信号列表。always @(negedge Resetn , posedge Clock)//请在括号中补充敏感信号列表。always @(negedge Resetn,posedge Clock)//请在括号中补充敏感信号列表。//为了便于自动评测,请勿更改n的值。//为了便于自动评测,请勿更改n的值。//为了便于自动评测,请勿更改n的值。//为了便于自动评测,请勿更改n的值。

M_inherit的博客 360

ComfyUI 局部重绘工作流示例

本文介绍了使用ComfyUI进行图像局部重绘的基础工作流程,重点讲解如何修改人物眼睛颜色和表情。主要内容包括:1.准备工作(可选下载DreamShaperv8模型);2.加载素材图片和工作流文件;3.使用遮罩编辑器绘制需要修改的区域;4.修改提示词控制生成内容;5.调整denoise参数优化效果。教程提供了详细的提示词示例(如"smile,blackeyes"等)和参数设置建议,帮助用户通过多次尝试获得理想效果。该工作流适用于修改图像局部区域而不影响整体画面。

云域A的博客 331

Rust 中的智能指针机制:Box、Rc、Arc 的选择艺术

Rust 的智能指针系统是其所有权模型的自然延伸,但也是最容易被误解的部分。Box<T>、Rc<T> 和 Arc<T> 三种智能指针虽然看似简单,但它们各自解决了不同的所有权问题,对应着不同的执行模型。掌握何时、为什么以及如何使用每一种指针,是从 Rust 初学者进阶到系统工程师的关键门槛。

2301_81152266的博客 1081

Python 爬虫实战:共享单车数据采集全流程与市场洞察深度剖析

本文介绍了如何利用Python爬虫技术获取和分析共享单车运营数据。文章从项目背景出发,详细阐述了系统架构设计,包括数据抓取、清洗存储、分析和可视化模块。通过Scrapy、BeautifulSoup等工具实现数据采集,使用Pandas进行数据清洗,并借助Matplotlib进行可视化分析。实战部分展示了爬虫代码示例和城市分布、使用频率等分析案例。最终指出数据驱动分析有助于了解行业现状和市场趋势,未来可结合机器学习等方法进行深入洞察。该技术方案为共享单车行业研究提供了有效的数据支持。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2232

rust智能指针

Deref隐式转换将实现了Deref的类型的引用转换为另一种类型的引用。一种无法在编译时知道大小的类型是递归类型,其值的一部分可以是自身类型的另一个值。Deref trait使智能指针表现的像引用一样,这样就可以编写既用于引用、又用于智能指针的代码。每次使用 * 时, * 运算符都被替换成先调用deref方法再使用 * 解引用的操作,且只会发生一次,不会无限递归替换 * 操作符,解引用出i32类型的值就停止了。是一个指针,它的大小是确定的,所以将Box作为Cons的成员,这样List的大小就确定了。

void的博客 875

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

RUST笔记:初识RefCell

初识RefCell

m0_54948954的博客 713

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【Rust中的智能指针】

传统的指针,如C++中的裸指针,需要开发者自己申请和释放,如果开发者在使用过程中疏漏了回收,将会造成内存泄漏,在部署实施时也会有oom的风险,智能指针即是为了解决这类问题而出现的,老生常谈的shared_ptr,unique_ptr,weak_ptr等,都是通过设计使得代码自动管理回收堆上的内存,提高代码的健壮性和方便性。Rust由于其严格的安全性和所有权机制,除unsafe写法外,所有的堆内存都是通过语言特性管理的。

m0_37719524的博客 1233

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Rust语言教程(8) - 所有权

Rust语言教程(8) - 所有权 我们从第2讲到第7讲这6讲,在堆上分配了不少对象,但是类似于C++的delete运算符仍然没有出场过。因为Rust有作用域规则,在超出作用域之后会自动释放掉。 移动语义和复制语义 我们来复习下移动语义。 先看一段代码: let mut c_0 = Complex{real:0, imagine:0}; println!("{}",c_0); println!("{}",c_0.imagine); println!("{:?}",c_0);

lusing的专栏 400

rust学习——智能指针

Rust 标准库中定义的那些智能指针,虽重但强,可以提供比引用更多的功能特性,例如本章将讨论的引用计数智能指针。该智能指针允许你同时拥有同一个数据的多个所有权,它会跟踪每一个所有者并进行计数,当所有的所有者都归还后,该智能指针及指向的数据将自动被清理释放。而智能指针则不然,它虽然也号称指针,但是它是一个复杂的家伙:通过比引用更复杂的数据结构,包含比引用更多的信息,例如元数据,当前长度,最大可用长度等。,它们的数据结构中不仅仅包含了指向底层数据的指针,还包含了当前长度、最大长度等信息,其中。

mirana的专栏 938

rust复习笔记5

构建命令行程序 获取命令行参数的值,我们需要一个 Rust 标准库提供的函数,也就是std::env::args。 当所需函数嵌套了多于一层模块时,通常将父模块引入作用域,而不是其自身。 std::fs来处理文件 获取环境变量的方法,env::var(环境变量名) 标准库提供了eprintln!宏来打印到标准错误流 闭包 闭包的定义以一对竖线(|)开始,在竖线中指定闭包的参数...

luo222的专栏 323

rust实战系列三十:静态方法

Box的一系列方法Box::into_raw(b: Self)Box::leak(b:Self),以及Rc的一系列方法Rc::try_unwrap(this: Self)Rc::downgrade(this:&Self),都是这种情况。它们的receiver不是self关 键字,这样设计的目的是强制用户用Rc::downgrade(&obj)的形式调用,而禁 止obj.downgrade()形式的调用。没有receiver参数的方法(第一个参数不是self参数的方法)称作“静态方法”。

Mr_Roki的博客 517

Rust 的智能指针

Rust 的智能指针

一起coding,一起嗨。 604

指针的三种面孔:深度拆解 Rust 中的 Box、Rc 与 Arc

的差异与内部机制,我们能在 Rust 项目中更加自信地管理内存与所有权:既保持安全,也守住性能边界。由于 Arc 只保证引用计数安全,内部数据仍需同步原语保护。应按并发需求选择,并在热路径减少克隆次数。提供独占所有权:内部仅包含一个指向被管理对象的裸指针,结合实现运行时可变性,但要防范循环引用导致的内存泄漏。允许与 C 交互,但需确保只调用一次还原。支持写时复制,独占时可直接修改底层数据。通过两粒引用计数跟踪共享状态:强引用。:多线程安全的原子引用计数结构,通过。实现锁自由的计数更新。

TD0011的博客 344

Rust开发入门之Rust 智能指针详解

Rust 智能指针是其内存安全机制的重要组成部分,通过所有权系统实现高效安全的内存管理。标准库提供了多种智能指针:Box<T>用于堆分配和递归类型;Rc<T>实现单线程的多所有权共享;Arc<T>是其线程安全版本;RefCell<T>提供内部可变性,将借用检查推迟到运行时。这些指针通过实现Deref和Drop特征,支持自动解引用和资源清理。合理组合使用这些指针(如Rc<RefCell<T>>)可以在遵循Rust安全规则的同时满足复杂场景

风中追风 994

Rust智能指针的奇妙之旅:从踩坑到顿悟

上个月我在写一个多线程文件处理工具时,程序莫名其妙地崩了。错误信息指向一个看似平常的变量传递,编译器冷冷地告诉我:“value moved here”。那一刻我才意识到,是时候认真搞懂Rust的智能指针了。Box、Rc、Arc,这三个家伙看起来都是在管理内存,但它们各自的脾气和适用场景完全不同。

L040821的博客 491
上一篇: 多个closure引用同一个变量,并且可能需要mut borrow
下一篇: 含有重复元素的二分查找算法
varding
博客等级 码龄17年 115粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值