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

借用和引用

文章目录

  • 所有权
  • 引用和借用
    • 可变引用
    • 悬垂引用

所有权

Rust通过所有权来管理内存,最妙的是,这种检查只发生在编译期,因此对于程序运行期,不会有任何性能上的损失。

使用堆和栈的性能区别:

写入方面:入栈比在堆上分配内存要快。 因为入栈时操作系统无需分配新的空间,只需要将新数据放入栈顶即可。相比之下,在堆上分配内存则需要更多的工作,这是因为操作系统必须首先找到一块足够存放数据的内存空间,接着做一些记录为下一次分配做准备。

读取方面:出栈比读取堆上的数据快。 栈数据往往可以直接存储在 CPU 高速缓存中,而堆数据只能存储在内存中。访问堆上的数据比访问栈上的数据慢,因为必须先访问栈再通过栈上的指针来访问内存。

因此,处理器处理分配在栈上数据会比在堆上的数据更加高效。

Rust的所有权原则:

  1. Rust 中每一个值都被一个变量所拥有,该变量被称为值的所有者
  2. 一个值同时只能被一个变量所拥有,或者说一个值只能拥有一个所有者
  3. 当所有者(变量)离开作用域范围时,这个值将被丢弃(drop)

简单说就是每一个值(堆上的值)有且只有一个所有者(变量),当这个变量出了作用域,那么这个值也被丢弃(在堆上也会丢弃)。

看一段代码:

fn main(){let x: &str = "hello world";let y = x;println!("{},{}",x,y);
}

这段代码并不会报错,这是因为 x 在这里只是引用了字符串,没有所有权,所以 let y = x; 是对引用的拷贝,不会有所有权的转移(具体看下一节 “引用与借用” )

函数的传参和返回:

传参:

fn main() {let s = String::from("hello");  // s 进入作用域takes_ownership(s);             // s 的值移动到函数里 // s 所以到这里不再有效let x = 5;                      // x 进入作用域makes_copy(x);                  // x 应该移动函数里,// 但 i32 是 Copy 的,所以在后面可继续使用 x} // 这里, x 先移出了作用域,然后是 s。但因为 s 的值已被移走,// 所以不会有特殊操作fn takes_ownership(some_string: String) { // some_string 进入作用域println!("{}", some_string);
} // 这里,some_string 移出作用域并调用 `drop` 方法。占用的内存被释放fn makes_copy(some_integer: i32) { // some_integer 进入作用域println!("{}", some_integer);
} // 这里,some_integer 移出作用域。不会有特殊操作

返回:

fn main() {let s1 = gives_ownership();         // gives_ownership 将返回值移给 s1let s2 = String::from("hello");     // s2 进入作用域let s3 = takes_and_gives_back(s2);  // s2 被移动到takes_and_gives_back 中,它也将返回值移给 s3
} 
// 这里, 
// s3 移出作用域并被丢弃。
// s2 也移出作用域,但已被移走,所以什么也不会发生。
// s1 移出作用域并被丢弃fn gives_ownership() -> String {  let some_string = String::from("hello"); // some_string 进入作用域.some_string                              // 返回 some_string 并移出给调用的函数
}// takes_and_gives_back 将传入字符串并返回该值
fn takes_and_gives_back(a_string: String) -> String { // a_string 进入作用域a_string  // 返回 a_string 并移出给调用的函数
}

引用和借用

在 Rust 中,获取变量的引用叫做借用

引用:&x,解引用:*x;

用在函数参数和函数返回值:

fn main() {let s1 = String::from("hello");let len = calculate_length(&s1);println!("The length of '{}' is {}.", s1, len);
}fn calculate_length(s: &String) -> usize {s.len()
}

可变引用

引用默认是不能修改值的,想要修改值需要使用可变引用:

fn main() {let mut s = String::from("hello");change(&mut s);
}fn change(some_string: &mut String) {some_string.push_str(", world");
}

要注意的是,特定数据的可变引用在同一个作用域只能存在一个,并且,可变引用和不可变引用不能同时存在。

新旧编译器的引用作用域不同,旧编译器(1.31之前)的引用作用域结束于最近的花括号处,而新编译器的引用作用域改变为 最后一次使用的位置。

这种优化行为叫做 Non-Lexical LifeTimes(NLL).

悬垂引用

指引用指向某个值后,值被释放掉,指针仍然存在的情况。

在 Rust 中编译器可以确保引用永远也不会变成悬垂状态:当你获取数据的引用后,编译器可以确保数据不会在引用结束前被释放,要想释放数据,必须先停止其引用的使用。

释放引用:

fn dangle() -> &String { // dangle 返回一个字符串的引用let s = String::from("hello"); // s 是一个新字符串&s // 返回字符串 s 的引用
} // 这里 s 离开作用域并被丢弃。其内存被释放。// 危险!// 应该更改为
fn no_dangle() -> String {let s = String::from("hello");s
}

相关文章:

借用和引用

文章目录 所有权引用和借用可变引用悬垂引用 所有权 Rust通过所有权来管理内存,最妙的是,这种检查只发生在编译期,因此对于程序运行期,不会有任何性能上的损失。 使用堆和栈的性能区别: 写入方面:入栈比在…...

WPF上位机9——Lambda和Linq

Lambda Linq 操作集合 使用类sql形式查询 Linq To SQL...

从0到1搭建uniapp

一、什么是uniapp UniApp是一款基于Vue.js框架的全端开发工具,可以实现同时开发多个平台(包括H5、小程序、APP等)应用的能力。使用UniApp,开发者只需要编写一份代码就可以快速地发布到多个平台,极大地提高了开发效率和…...

安全杂记 - Linux文本三剑客之awk

目录 1.什么是AWK2.正则表达式3.语法4.内置变量示例printf命令5.复现awk经典实例(1).插入几个新字段(2).格式化空白(3).筛选IPv4地址(4).筛选给定时间范围内的日志 1.什么是AWK awk、grep、sed是linux操作文本的三大利器,合称文本三剑客。三者的功能都是处理文本&a…...

Android 开发者选项日志存储路径

android开发者选项中存在两个item是关于系统日志的。 1.日志记录器缓冲区大小 2.在设备上永久存储日志记录器数据 一个是用来设置缓冲区大小,一个是用来日志存储开关及过滤。 通过分析 system/core/logcat/logcatd.rc mkdir /data/misc/logd 0770 logd log 日志的…...

jupyter lab build失败,提示需要安装版本>=12.0.0的nodejs但其实已从官网安装18.17.0版本 的解决方法

出现的问题如题目所示,这个问题差点要把我搞死了。。。但还是在没有重装的情况下解决了😘。 问题来源 初衷是想安装lsp扩展,直接在jupyter lab网页界面的extensions中搜索lsp并点击install krassowski/jupyterlab-lsp,会提示需要…...

【set】个人练习-Leetcode-817. Linked List Components

题目链接&#xff1a;https://leetcode.cn/problems/linked-list-components/description/ 题目大意&#xff1a;给出一个vector<int> nums&#xff0c;其中有一些数字。再给出一个链表的头指针head&#xff0c;链表内的元素各不相同。如果链表中有某一段&#xff08;长…...

Linux IPIP隧道连通两个局域网

拓扑结构 现有两台主机&#xff0c;它们具有两个网口分别接入到不同网络中。 主机A&#xff1a; eth0&#xff1a;处于 10.0.1.2/24 网段eth1&#xff1a; 处于192.168.1.100/24 网段 主机B&#xff1a; eth0&#xff1a;处于10.0.2.3/24 网段eth1&#xff1a; 处于192.168.2…...

华为QinQ技术的基本qinq和灵活qinq 2种配置案例

基本qinq配置&#xff1a; 运营商pe设备在收到同一个公司的ce发来的的包&#xff0c;统一打上同样的vlan &#xff0c;如上图&#xff0c;同一个家公司两边统一打上vlan 2&#xff0c;等于在原内网vlan 10或20过来的包再统一打上vlan 2的标签&#xff0c;这样传输就不会和其它…...

python爬虫1:基础知识

python爬虫1&#xff1a;基础知识 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 目录结构 文章目录 python爬虫1&#xff1a;基础知识1. 基础认知1.1 什么是爬虫&…...

【FAQ】安防监控视频EasyCVR平台分发的FLV视频流在VLC中无法播放

众所周知&#xff0c;TSINGSEE青犀视频汇聚平台EasyCVR可支持多协议方式接入&#xff0c;包括主流标准协议国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。在视频流的处理与分发上&#xff0c;视频监控…...

python爬虫2:requests库-原理

python爬虫2&#xff1a;requests库-原理 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 目录结构 文章目录 python爬虫2&#xff1a;requests库-原理1. 概述2. re…...

纹理贴图和渲染

纹理贴图 纹理映射&#xff08;也就是纹理图或者叫做纹理贴图&#xff09;是一种在计算机图形学中常用的技术&#xff0c;它可以将二维的图像&#xff08;纹理&#xff09;映射到三维物体的表面上&#xff0c;以增强视觉效果。“atlas”通常是指纹理图集&#xff0c;也就是将多…...

BLIP2

BLIP2的任务是基于已有的固定参数的图像encoder和语言大模型&#xff08;LLM&#xff09;搭建一个具有图像理解能力的图文模型&#xff0c;输入是图像和文本&#xff0c;输出是文本。 BLIP2基于Q-Former结构&#xff0c;如下图所示。Q-Former包含图像transformer和文本transfo…...

陀螺玩具跨境电商亚马逊CPC认证

陀螺指的是绕一个支点高速转动的刚体。陀螺是中国民间最早的娱乐工具之一.形状上半部分为圆形&#xff0c;下方尖锐。从前多用木头制成&#xff0c;现代多为塑料或铁制。玩时可用绳子缠绕&#xff0c;用力抽绳&#xff0c;使直立旋转。或利用发条的弹力旋转。传统古陀螺大致是木…...

TS学习02-接口

接口 ts原则之一就是对值所具有的结构进行类型检查。 结构的左右就是为了这些类型命名和代码定义契约 interface LabelValue {label: string } function point(label: LabelValue) {} let obj {label:标题&#xff0c;age: 18} point(obj)类型检查器不会去检查属性的顺序&a…...

WuThreat身份安全云-TVD每日漏洞情报-2023-08-09

漏洞名称:致远OA文件上传漏洞 漏洞级别:高危 漏洞编号:NULL 相关涉及:1. A6、A8、A8N的V8.0SP2、V8.1、V8.1SP1 漏洞状态:POC 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-19494 漏洞名称:Microsoft Exchange Server 欺骗漏洞 漏洞级别:高危 漏洞编号:CV…...

6. C++类的静态成员

一、对象的生产期 生存期&#xff1a;对象从诞生到结束的这段时间生存期分为静态生存期和动态生存期 1.1 静态生存期 对象的生存期与程序的运行期相同&#xff0c;则称它具有静态生存期在文件作用域中声明的对象都是具有静态生存期的若在函数内部的局部作用域中声明具有静态…...

如何使Python Docker镜像安全、快速、小巧

一、说明 在微服务领域&#xff0c;拥有安全、高效和紧凑的 Docker 映像对于成功部署至关重要。本博客将探讨有助于构建此类映像的关键因素&#xff0c;包括不以 root 用户身份运行映像的重要性、在构建映像时更新和升级包、在编写 Dockerfile 指令时考虑 Docker 的层架构&…...

AWS——03篇(AWS之Amazon S3(云中可扩展存储)-01入门)

AWS——03篇&#xff08;AWS之Amazon S3&#xff08;云中可扩展存储&#xff09;-01入门&#xff09; 1. 前言2. 关于 Amazon S32.1 介绍2.1.1 简述2.1.2 详细介绍 2.2 Amazon S3 好处和功能2.3 3. 创建S3存储桶3.1 创建存储桶3.2 修改访问权限 4. 简单实用4.1 上传图片文件4.2…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...