当前位置: 首页 > news >正文

rust学习Cell、RefCell、OnceCell

背景

Rust 内存安全基于以下规则:给定一个对象 T,它只能具有以下之一:

  • 对对象有多个不可变引用 (&T)(也称为别名 aliasing)
  • 对对象有一个可变引用 (&mut T)(也称为可变性 mutability)

这是由 Rust 编译器强制执行的。然而,在某些情况下,该规则不够灵活(this rule is not flexible)。有时需要对一个对象有多个引用并对其进行修改(it is required to have multiple references to an object and yet mutate it)。

可共享的可变容器的存在是为了以受控的方式允许可变性(permit mutability in a controlled manner),即使存在别名(in the presence of aliasing)也是如此。 Cell、RefCell 和 OnceCell 允许以单线程方式执行此操作,它们不实现 Sync。(如果需要在多个线程之间进行别名和突变 do aliasing and mutation among multiple threads,Mutex、RwLock、OnceLock 或原子类型是执行此操作的正确数据结构)。

介绍

Cell、RefCell 和 OnceCell 类型的值可以通过共享引用(即公共 &T 类型)进行mutate,而大多数 Rust 类型只能通过唯一 (&mut T) 引用(unique reference)进行mutate。
这些cell类型提供了“内部可变性,interior mutability”(通过 &T 可变),与表现出“继承可变性”(仅通过 &mut T 可变)的典型 Rust 类型形成鲜明对比。

Cell类型分为三种类型:Cell、RefCell 和 OnceCell。每个都提供了一种不同的方式来提供安全的内部可变性(providing safe interior mutability)。

Cell

Cell 通过将值移入和移出cell来实现内部可变性(interior mutability)。也就是说,永远无法获得内部值的 &mut T,并且如果不将其替换为其他值,则无法直接获得该值本身。
这两条规则都确保永远不会有多个引用指向内部值。
该类型提供了以下方法:

  • 对于实现 Copy 的类型, get 方法通过复制当前内部值来检索它
  • 对于实现 Default 的类型, take 方法用 Default::default() 替换当前内部值并返回替换的值

所有的类型拥有:

  • replace:替换当前内部值并返回替换后的值
  • into_inner:此方法消耗 Cell 并返回内部值
  • set:此方法替换内部值,删除替换的值

Cell 通常用于更简单的类型,其中复制或移动值不太占用资源(例如数字),并且在可能的情况下通常应优先于其他cell类型。对于较大的no-copy类型,RefCell 提供了一些优势。

RefCell

RefCell 使用 Rust 的生命周期来实现“动态借用 dynamic borrowing”,这是一个可以声明对内部值的临时、独占、可变访问的过程(claim temporary, exclusive, mutable access)。 RefCell 的借用是在运行时跟踪的,这与 Rust 的引用类型(native reference)不同,后者在编译时完全静态跟踪。

对 RefCell 内部值的不可变引用 (&T) 可以通过 Borrow 获得,可变借用(mutable borrow) (&mut T)可以通过 Borrow_mut 获得。
当这些函数被调用时,它们首先验证 Rust 的借用规则是否得到满足:允许任意数量的不可变借用或允许单个可变借用,但决不能两者兼而有之。如果尝试借用违反这些规则,线程将出现panic。

RefCell 对应的 Sync 版本是 RwLock。

OnceCell

OnceCell 有点像 Cell 和 RefCell 的混合体(somewhat of a hybrid of Cell and RefCell),适用于通常只需要设置一次的值。这意味着无需移动或复制内部值(与 Cell 不同),也无需运行时检查(与 RefCell 不同)即可获取引用 &T。
但是,它的值一旦设置就无法更新,除非有对 OnceCell 的可变引用。
OnceCell提供了以下方法:

  • get:获取内部值的引用
  • set:如果未设置则设置内部值(返回Result)
  • get_or_init:返回内部值,如果需要则初始化它
  • get_mut:提供对内部值的可变引用,仅当有对单元格本身的可变引用时才可用
    OnceCell 对应的Sync版本是 OnceLock

只能写入一次的 cell (which can be written to only once)
这允许获取对其内部值的共享 &T 引用,而无需复制或替换它(与 Cell 不同),并且无需运行时借用检查(与 RefCell 不同)。但是,除非对 Cell 本身具有可变引用,否则只能获得不可变引用。
有关此结构的线程安全版本,请参阅 std::sync::OnceLock

use std::cell::OnceCell;fn main(){let cell = OnceCell::new();assert!(cell.get().is_none());let value: &String = cell.get_or_init(|| {"Hello, World!".to_string()});assert_eq!(value, "Hello, World!");assert!(cell.get().is_some());
}
pub fn get(&self) -> Option<&T>

获取对内部值的引用,如果Cell为空,则返回Null

pub fn get_or_init<F

相关文章:

rust学习Cell、RefCell、OnceCell

背景 Rust 内存安全基于以下规则:给定一个对象 T,它只能具有以下之一: 对对象有多个不可变引用 (&T)(也称为别名 aliasing)对对象有一个可变引用 (&mut T)(也称为可变性 mutability)这是由 Rust 编译器强制执行的。然而,在某些情况下,该规则不够灵活(this r…...

基于SSM的摄影约拍系统

基于SSM的摄影约拍系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisJSP工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 前台系统&#xff1a;首页拍摄作品展示、摄影师展示、模特展示、文章信息、交流论…...

分析智能平台VMware Greenplum 7 正式发布!

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…...

动态规划算法(3)--0-1背包、石子合并、数字三角形

目录 一、0-1背包 1、概述 2、暴力枚举法 3、动态规划 二、石子合并问题 1、概述 2、动态规划 3、环形石子怎么办&#xff1f; 三、数字三角形问题 1、概述 2、递归 3、线性规划 四、租用游艇问题 一、0-1背包 1、概述 0-1背包&#xff1a;给定多种物品和一个固定…...

Linux C/C++ 嗅探数据包并显示流量统计信息

嗅探数据包并显示流量统计信息是网络分析中的一种重要技术&#xff0c;常用于网络故障诊断、网络安全监控等方面。具体来说&#xff0c;嗅探器是一种可以捕获网络上传输的数据包&#xff0c;并将其展示给分析人员的软件工具。在嗅探器中&#xff0c;使用pcap库是一种常见的方法…...

Vitis导入自制IP导致无法构建Platform

怎么还有这种问题&#xff08; 解决Vitis导入自制IP导致无法构建Platform – TaterLi 个人博客 Vitis报错&#xff1a;fatal error: xxx.h: No such file or directory._ly2lj的博客-CSDN博客 在指定位置黏入以上代码即可&#xff1a; INCLUDEFILES$(wildcard *.h) LIBSOUR…...

SQLAlchemy 使用封装实例

类封装 database.py #! /usr/bin/env python # -*- coding: utf-8 -*-import sys import json import logging from datetime import datetimefrom core.utils import classlock, parse_bool from core.config import (MYSQL_HOST,MYSQL_PORT,MYSQL_USER,MYSQL_PASS,MYSQL_DA…...

Android Framework通信:Binder

文章目录 前言一、Linux传统跨进程通信原理二、Android Binder跨进程通信原理1、动态内核可加载模块2、内存映射3、Binder IPC 实现原理 三、Android Binder IPC 通信模型1、Client/Server/ServiceManager/驱动Binder与路由器之间的角色关系 2、Binder通信过程3、Binder通信中的…...

如何用精准测试来搞垮团队?

测试行业每年会冒出来一些新鲜词&#xff1a;混沌工程、精准测试、AI测试…… 这些新概念、新技术让我们感到很焦虑&#xff0c;逼着自己去学习和了解这些新玩意&#xff0c;担心哪一天被淘汰掉。 以至于给我这样的错觉&#xff0c;当「回归测试」、「精准测试」这两个词摆在一…...

暴力递归转动态规划(十)

题目 给定一个二维数组matrix[][]&#xff0c;一个人必须从左上角出发&#xff0c;最终到达右下角&#xff0c;沿途只可以向下或者向右走&#xff0c;沿途的数字都累加就是距离累加和。返回最小距离累加和。 这道题中会采用压缩数组的算法来进行优化 暴力递归 暴力递归方法的整…...

深度学习-房价预测案例

1. 实现几个函数方便下载数据 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载…...

【26】c++设计模式——>命令模式

c命令模式 C的命令模式是一种行为模式&#xff0c;通过将请求封装成对象&#xff0c;以实现请求发送者和接受者的解耦。 在命令模式中&#xff0c;命令被封装成一个包含特定操作的对象&#xff0c;这个对象包含的执行该操作的方法&#xff0c;以及一些必要的参数。命令对象可以…...

ElasticSearch容器化从0到1实践(一)

背景 通过kubernetes集群聚合多个Elasticsearch集群碎片资源&#xff0c;提高运维效率。 介绍 Kubernetes Operator 是一种特定的应用控制器&#xff0c;通过 CRD&#xff08;Custom Resource Definitions&#xff0c;自定义资源定义&#xff09;扩展 Kubernetes API 的功能…...

【Vue面试题二十四】、Vue项目中有封装过axios吗?主要是封装哪方面的?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;Vue项目中有封装过axios…...

旅游票务商城小程序的作用是什么

随着环境放开&#xff0c;旅游行业恢复了以往的规模&#xff0c;本地游、外地游成为众多用户选择&#xff0c;而在旅游时&#xff0c;不少人会报名旅行团前往各风景热点游玩&#xff0c;对旅游票务经营者而言&#xff0c;市场高需求的同时也面临一些难题。 对旅游票务经营商家…...

LabVIEW在安装了其它的NI软件之后崩溃了

LabVIEW在安装了其它的NI软件之后崩溃了 在安装了其它的NI软件之后&#xff0c;一些原本安装好的或者新安装的软件由于缺少必要的DLL而崩溃掉了。例如&#xff0c;在这种情况下&#xff0c;Teststand可能会报下面的错误&#xff1a; RetrievingCOM class factory for compone…...

基于Java的个人健康管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

nginx https的配置方法

文章目录 安装证书工具安装根证书生成域名证书配置转发 ssl的请求到http请求 安装证书工具 curl ‘http://pan.itshine.cn:5080/?explorer/share/fileOut&shareID64h6PiQQ&path%7BshareItemLink%3A64h6PiQQ%7D%2F%E5%B7%A5%E5%85%B7%2Fmkcert’ > ‘./mkcert’ c…...

使用WebDriver采样器将JMeter与Selenium集成

目录 第一步&#xff1a;在JMeter中添加Selenium / WebDriver插件 第二步&#xff1a;创建一条测试计划--添加线程组 第三步&#xff1a;下载 chromedriver.exe 第四步&#xff1a;在Web Driver 采样器中添加测试脚本 第五步&#xff1a;运行并且验证 注意&#xff1a; 第…...

flink教程

文章目录 来自于尚硅谷教程1. Flink概述1.1 特点1.2 与SparkStreaming对比 2. Flink部署2.1 集群角色2.2 部署模式2.3 Standalone运行模式2.3.1 本地会话模式部署2.3.2 应用模式 2.4 YARN运行模式2.4.1 会话模式部署2.4.2 应用模式部署 2.5 历史服务 3. 系统架构3.1 并行度3.2 …...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...