当前位置: 首页 > 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…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...