恋爱脑学Rust之智能指针Rc,RefCell和Weak指针

在这里插入图片描述

小明和小丽为了维系彼此的关系,一起探索了智能指针的奥秘。通过 RcRefCellWeak 的帮助,他们得以克服情感中遇到的种种困境。

第一章:Rc 智能指针的共生

小明和小丽搬进了一个共同的小屋,他们彼此相爱,决定共用一个拥有自己专属家具的房间。用 Rc 类型来表达这一关系,它是一个引用计数智能指针,可以让多个持有者安全地共享数据。

场景1:共享数据

假如在这个故事中,我们没有 Rc 这样的支持,那么如果小明和小丽都需要访问同一个房间的家具(Room),会导致所有权冲突:

struct Room {
    furniture: String,
}

fn main() {
    let shared_room = Room {
        furniture: String::from("Shared Bed"),
    };

    // 如果不使用 Rc,无法让两个变量共享同一个 Room
    let ming_room = shared_room; // 转移所有权到 ming_room
    let li_room = shared_room; // 报错:无法重复所有权
}

这个错误正如小明和小丽无法同时拥有同一个家具一样。Rc 的出现解决了这个问题,让共享变得可能:

use std::rc::Rc;

struct Room {
    furniture: String,
}

fn main() {
    // 使用 Rc 实现共享房间
    let shared_room = Rc::new(Room {
        furniture: String::from("Shared Bed"),
    });

    let ming_room = Rc::clone(&shared_room); // 克隆 Rc 增加引用计数
    let li_room = Rc::clone(&shared_room);

    println!("Ming's furniture: {}", ming_room.furniture);
    println!("Li's furniture: {}", li_room.furniture);
}
解释

Rc 允许小明和小丽共享房间,而不会因为一个人拿走所有权而导致另一个人无法访问。

第二章:RefCell 智能指针的理解与沟通

在相处的过程中,小明发现他们的房间(即数据)需要在某些时候进行修改,而 Rc 默认是只读的。于是 RefCell 出现了,这种智能指针允许在运行时执行可变借用检查。它就像他们的沟通桥梁,确保修改安全。

场景2:内部可变性

在没有 RefCell 时,试图修改 Rc 所指向的数据会导致编译错误:

use std::rc::Rc;

struct Room {
    furniture: String,
}

fn main() {
    let shared_room = Rc::new(Room {
        furniture: String::from("Shared Bed"),
    });

    // 无法直接修改 Rc 所指向的数据
    shared_room.furniture = String::from("New Bed"); // 错误
}

但是 RefCell 允许我们内部修改 Rc 所指向的数据:

use std::rc::Rc;
use std::cell::RefCell;

struct Room {
    furniture: RefCell<String>,
}

fn main() {
    let shared_room = Rc::new(Room {
        furniture: RefCell::new(String::from("Shared Bed")),
    });

    // 使用 borrow_mut() 修改 RefCell 内部的数据
    *shared_room.furniture.borrow_mut() = String::from("New Bed");

    println!("Updated furniture: {}", shared_room.furniture.borrow());
}
解释

在这个故事中,RefCell 为小明和小丽提供了沟通方式,避免了访问冲突,确保他们可以顺利商讨并更新房间的布置。

第三章:Weak 智能指针的回忆与淡忘

随着时间的推移,小明和小丽的爱情逐渐淡去,他们的联系变成了不再紧密的弱引用Weak 可以让他们保留彼此的联系,但不会增加引用计数,防止循环引用带来的内存泄漏。

场景3:避免循环引用

假如小明和小丽各自对彼此的联系是强引用(Rc),则会导致循环引用,使内存无法释放:

use std::rc::Rc;
use std::cell::RefCell;

struct Person {
    name: String,
    partner: Rc<RefCell<Option<Rc<Person>>>>,
}

fn main() {
    let ming = Rc::new(Person {
        name: String::from("Ming"),
        partner: RefCell::new(None),
    });
    let li = Rc::new(Person {
        name: String::from("Li"),
        partner: RefCell::new(Some(Rc::clone(&ming))),
    });
    
    *ming.partner.borrow_mut() = Some(Rc::clone(&li));

    // 错误:相互的 Rc 循环引用导致内存无法回收
}

这里,Weak 可以避免这种情况,彼此联系不会持有强引用:

use std::rc::{Rc, Weak};
use std::cell::RefCell;

struct Person {
    name: String,
    partner: RefCell<Option<Weak<Person>>>,
}

fn main() {
    let ming = Rc::new(Person {
        name: String::from("Ming"),
        partner: RefCell::new(None),
    });
    let li = Rc::new(Person {
        name: String::from("Li"),
        partner: RefCell::new(Some(Rc::downgrade(&ming))),
    });
    
    *ming.partner.borrow_mut() = Some(Rc::downgrade(&li));

    // 使用 Weak 指针,不会增加引用计数
    println!("Ming's partner: {:?}", ming.partner.borrow().as_ref().unwrap().upgrade());
}
解释

Weak 就像一份美好的回忆,它不会真正占据内存,避免了循环引用导致的内存泄漏,同时也能提供必要的联系。

总结

  • Rc:提供共享的强引用,用于安全共享的场景。
  • RefCell:内部可变性,解决运行时的可变借用问题。
  • Weak:弱引用,防止循环引用带来的内存泄漏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/907181.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第530题二叉搜索树的最小绝对差

题目&#xff1a; 题解&#xff1a; void dfs(struct TreeNode* root, int* pre, int* ans) {if (root NULL) {return;}dfs(root->left, pre, ans);if (*pre -1) {*pre root->val;} else {*ans fmin(*ans, root->val - (*pre));*pre root->val;}dfs(root->…

image_points_to_world_plane详解

分三个部分来聊聊这个算子 一,算子的参数介绍 二,算法的计算过程 三,举例实现 第一部分,算子的介绍 image_points_to_world_plane( : : CameraParam, WorldPose, Rows, Cols, Scale : X, Y) 参数介绍: CameraParam,:相机内参 WorldPose 世界坐标系,也叫物体坐标系(成…

“发放父作业单”是“过数”用例里面的内容吗

刘京城 2020-4-14 23:01 。。。。(注&#xff1a;这是一个人的昵称&#xff0c;不是省略号) 首先&#xff0c;执行者是同一个&#xff0c;那么思考焦点要关注“过数”用例是不是“发放父作业单”用例的一个步骤&#xff0c;和行为操作的频率无关&#xff0c;而是和责任有关&am…

vue3 ref,shallowRef,reactive,shallowReactive使用的简单异同点说明

1、这几个都是负责data的存储及读取的&#xff0c;我们常用的是ref,reactive。 2、看一下shallowRef这个,shallowReactive与其类似。 说明&#xff1a;以官网的说明&#xff0c;这个state.value.count 2是不会触发视图更新的&#xff0c;但是如果直接在<script setup lang…

Java | Leetcode Java题解之第517题超级洗衣机

题目&#xff1a; 题解&#xff1a; class Solution {public int findMinMoves(int[] machines) {int tot Arrays.stream(machines).sum();int n machines.length;if (tot % n ! 0) {return -1;}int avg tot / n;int ans 0, sum 0;for (int num : machines) {num - avg;s…

二分,CF 2036 G - Library of Magic

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 G - Library of Magic 二、解题报告 1、思路分析 首先 query(1, n) a ^…

Llama 3.2 Vision Molmo:多模态开源生态系统基础

编者按&#xff1a; 视觉功能的融入对模型能力和推理方式的影响如何&#xff1f;当我们需要一个既能看懂图像、又能生成文本的 AI 助手时&#xff0c;是否只能依赖于 GPT-4V 这样的闭源解决方案&#xff1f; 我们今天为大家分享的这篇文章&#xff0c;作者的核心观点是&#xf…

【android12】【AHandler】【4.AHandler原理篇ALooper类方法全解】

AHandler系列 【android12】【AHandler】【1.AHandler异步无回复消息原理篇】-CSDN博客 【android12】【AHandler】【2.AHandler异步回复消息原理篇】-CSDN博客 【android12】【AHandler】【3.AHandler原理篇AHandler类方法全解】-CSDN博客 其他系列 本人系列文章-CSDN博客…

探索NetCat:网络流量监测与数据传输的利器

从简单的数据传输到复杂的网络调试&#xff0c;NetCat的灵活性和多功能性让人赞叹不已&#xff0c;在这篇文章中我将深入探讨NetCat的魅力&#xff0c;揭示它的基本功能、实用技巧以及在日常工作中的应用场景&#xff0c;发现如何用这一小工具提升的网络技能与效率。 目录 Net…

UE4安卓Gradle工程中的libUE4.so的生成原理

流程图 流程图放在最前面&#xff0c;下面是讲解。 libUE4.so 问&#xff1a;在UE4安卓开发中&#xff0c;libUE4.so即是符号表&#xff0c;又是引擎代码native&#xff0c;是吗&#xff1f; 答&#xff1a;是的&#xff0c;libUE4.so在UE4安卓开发中既包含符号表&#xff0c;…

wireshark抓包查看langchain的ChatOpenAI接口发送和接收的数据

1. 引入 当我们用vllm部署一个大模型&#xff0c;就可以调用langchain的ChatOpenAI()接口来访问大模型&#xff08;具体过程参考[1]&#xff09;&#xff0c;这也是langchain的Agent的基础接口使用方式。 那么问题来了&#xff0c;这个接口是使用哪种方式与大模型进行通信的呢…

ubuntu 24.04中安装 Easyconnect,并解决版本与服务器不匹配问题

下载安装包 下载地址 https://software.openkylin.top/openkylin/yangtze/pool/all/ 页面搜索 easyconnect 选择 easyconnect_7.6.7.3.0_amd64.deb安装 sudo dpkg --install easyconnect_7.6.7.3.0_amd64.deb卸载 sudo dpkg --remove easyconnect出现的问题 安装以后第…

arcgis坐标系问题

2000数据框的工程只能打开2000坐标系的矢量数据和栅格数据&#xff08;影像图&#xff09;&#xff0c;如果打开80的数据则会投影错误&#xff0c;出现较大偏差。 解决方案&#xff1a;80数据框打开80数据&#xff0c;2000数据库打开2000数据。

0-1规划的求解

实验类型&#xff1a;◆验证性实验 ◇综合性实验 ◇设计性实验 实验目的&#xff1a;学会使用Matlab编程实现求解0-1规划。 实验内容&#xff1a;1.学习使用Matlab定义子函数的命令function&#xff1b; 2.编程求解0-1型整数规划的枚举法或隐枚举法。 例1&#xff1a;求…

RNN与Self-Attention

文章目录 1. SimpleRNN1.1 h t h_t ht​计算1.2 激活函数 2. SimpleRNNSelf-Attention2.1 状态更新2.2 权重 α α α 1. SimpleRNN 学习视频&#xff1a;https://www.youtube.com/watch?vCc4ENs6BHQw&t0s 对于时序数据&#xff0c;输入输出都不固定&#xff0c;需要ma…

R-CNN,Fast R-CNN,

R-CNN R-CNN可以说是利用深度学习进行目标检测的开山之作 RCNN算法流程可分为4个步骤 - 一张图像生成1K~2K个候选区域(使用Selective Search方法) - 对每个候选区域&#xff0c;使用深度网络提取特征 - 特征送入每一类的SVM 分类器&#xff0c;判别是否属于该类 - 使用回归器…

C++/list

目录 1.list的介绍 2.list的使用 2.1list的构造 2.2list iterator的使用 2.3list capacity 2.4list element access 2.5list modifers 2.6list的迭代器失效 3.list的模拟实现 4.list与vector的对比 欢迎 1.list的介绍 list的文档介绍 cplusplus.com/reference/list/li…

人工智能证书合集

本文将对目前市面上主流官方机构颁发的人工智能证书进行整理和介绍&#xff0c;由于整理的证书较多&#xff0c;本文共一万八千多字&#xff0c;请根据自己的考证需求阅读对应部分的内容&#xff0c;希望本文对人工智能行业的从业人员和计划从事人工智能相关岗位工作的人员有所…

TongWeb7.0.E.6_P11嵌入式版本使用指引(by lqw)

文章目录 声明相关概念手册的使用示范工程安装工程介质 安装前准备示范工程参考&#xff08;spring-boot-helloWorld-2.x&#xff09;示范参考 声明 1.本文参考001_TongWeb_V7.0嵌入式版_JavaEE标准容器用户指南_70E6_P11A01.pdf&#xff0c;实际以最新更新的手册为准。 2.本文…

鸿蒙开发融云demo发送图片消息

鸿蒙开发融云demo发送图片消息 融云鸿蒙版是不带UI的&#xff0c;得自己一步步搭建。 这次讲如何发送图片消息&#xff0c;选择图片&#xff0c;显示图片消息。 还是有点难度的&#xff0c;好好看&#xff0c;好好学。 一、思路&#xff1a; 选择图片用&#xff1a;photoVie…