5.所有权
标题
- 一、概念
- 二、规则
- 三、示例
- 3.1 变量作用域
- 3.2 所有权的移交(深拷贝与浅拷贝)
- 3.3 函数与所有权
- 3.4 返回值与作用域
- 3.5 引用的使用
- 四、切片(&str)
一、概念
- 所有权是Rust的核心特性。
- 所有程序在运行时都必须管理它们使用计算机内存的方式。Rust的内存是通过一个所有权系统来管理的,其中包含一组编译器在编译时检查的规则。
- 在Rust中,一个值是在栈还是堆上对语言的行为和为什么要做某些决定是有更大的影响的。
- Rust通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查。在运行时,所有权系统的任何功能都不会减慢程序。
二、规则
- Rust 中的每一个值都有一个被称为其所有者(owner)的变量;
- 值在任一时刻有且只有一个所有者;
- 当所有者(变量)离开作用域,这个值将被
丢弃; - 函数参数的传递也会造成所有权的转移;
- 使用
引用可以只使用变量而不转移所有权; - 一个
引用的作用域从声明的地方开始一直持续到最后一次使用为止;
三、示例
3.1 变量作用域
- 下面的变量x超出了
{}的作用域范围,打印时报错cannot find value x in this scope hello变量自动在堆内存中申请了空间,并且初始化为hello,等出了作用域(倒数第二个“}”号)后自动调用drop函数释放内存。
fn main() {{let x = 3;} println!("x = {}", x); //cannot find value `x` in this scope{let hello = String::from("hello");println!("hello = {}", hello );}
}
3.2 所有权的移交(深拷贝与浅拷贝)
- 在堆上申请的内存,会在连续赋值的时候进行内存所有权的移交。
- 可以使用
clone函数进行堆内存的深拷贝
fn main() {let x = 5;let y = x; //栈内存,没有任何影响let h = String::from("HelloWorld!");let l = h; //已经进行了所有权的移交,h已不存在//let l = h.clone(); //可以使用clon()函数重新申请空间//println!("h = {}",h); //error: value borrowed here after move(clone除外)println!("l = {}",l);
}
3.3 函数与所有权
将值传递给函数在语义上与给变量赋值相似。所有权转移的规则也相同
fn main() {let s = String::from("Hello");take_ownership(s); //这里s发生了转移 let x = 5;makes_copy(x); //栈上的变量x不受所有权影响println!("{} {}", x, s); //s的所有权在take_ownership里,因此这里无法打印
}fn take_ownership(src: String){println!("{}", src);
}fn makes_copy(src: i32){println!("{}", src)
}
3.4 返回值与作用域
返回值可以把内存空间的所有权返回
fn main() {let s1 = gives_ownership(); //来源于gives_ownership中的some_stringlet s2 = String::from("hello"); let s3 = takes_and_gives_back(s2); //通过该函数所有权从s2转移到了s3println!("{}{}{}", s1, s2, s3); //s2编译报错}fn gives_ownership() -> String {let src = String::from("hello"); src //返回src的所有权
}fn takes_and_gives_back(a_string: String) -> String{a_string
}
3.5 引用的使用
在参数中使用引用就可以只传递变量而不传递所有权
fn main() {let mut s = String::from("Hello");alter_string_value(&mut s); //只传递s的值而不转移所有权println!("{}", s); //s依然有效,输出“Hello,world”
}fn alter_string_value(src: &mut String){ //可变引用src.push_str(",world");
}fn print_string_value(src: &String){src.push_str(",world"); //不可变引用,不能修改
}
在同一时间,只能有一个对某一特定数据的可变引用,尝试创建两个可变引用的代码将会失败。
fn main() {let mut s = String::from("hello");let r1 = &mut s;let r2 = &mut s;println!("{}, {}", r1, r2);
}
报错信息如下

这个报错说这段代码是无效的,我们不能在同一个作用域内多次将 s 作为可变变量。第一个可变的引用在 r1 中,并且必须持续到在 println! 中使用它,但是在那个可变引用的创建和它的使用之间,我们又尝试在 r2 中创建另一个可变引用,它引用了与 r1 相同的数据。
这样做是为了避免数据竞争,数据竞争由三个行为造成:
- 两个或更多指针同时访问同一数据。
- 至少有一个指针被用来写入数据。
- 没有同步数据访问的机制。
禁止同时使用可变与不可变引用
fn main() {let mut s = String::from("hello");let r1 = &s; // 没问题let r2 = &s; // 没问题let r3 = &mut s; // 大问题println!("{}, {}, and {}", r1, r2, r3);
}
改成下面这样就行了,依然是作用域的问题。
fn main() {let mut s = String::from("hello");let r1 = &s; // 没问题let r2 = &s; // 没问题println!("{} {}", r1, r2);let r3 = &mut s; // 没问题println!("{}", r3);
}
四、切片(&str)
- 切片(slice)允许引用集合中一段连续的元素序列,而不用引用整个集合;
- 字符串字面量就是切片,因此它是不可变的;
- 可以采用字符串切片&str作为参数类型,因此这样就可以同时接收String和&str类型的参数了;
- 定义函数时
使用字符串切片代替字符串引用会使我们的API更加通用,且不会损失任何功能;
切片示例
fn main() {let s = String::from("hello world!");let hello = &s[0..5]; //hello,取0到4字符, 也可以写成&s[..5]let world = &s[5..]; //world,取6到最后let whole = &s[..]; //整个字符串// s.clear();println!("*{}*",hello); //*hello*println!("*{}*",world); //* world!*println!("{}", whole); //hello world!
}
函数示例
fn main() {let s = String::from("hello world!");let wordIndex = first_world(&s[..]); //使用完整的切片println!("wordIndex = {}", wordIndex);let my_string_literal = "hello world";let wordIndex = first_world(&my_string_literal);println!("wordIndex = {}", wordIndex);}//获得第一个单词
fn first_world(s: &str) -> &str {let bytes = s.as_bytes(); //转换为字节序for (index, &item) in bytes.iter().enumerate(){if item == b' ' {return &s[..index];}}&s[..]
}
相关文章:
5.所有权
标题 一、概念二、规则三、示例3.1 变量作用域3.2 所有权的移交(深拷贝与浅拷贝)3.3 函数与所有权3.4 返回值与作用域3.5 引用的使用 四、切片(&str) 一、概念 所有权是Rust的核心特性。所有程序在运行时都必须管理它们使用计算机内存的方式。Rust的…...
RabbitMQ-工作模式(Publish模式Routing模式)
文章目录 发布/订阅(Publish/Subscribe)交换机临时队列绑定总体代码示例 路由(Routing)绑定直连交换机多重绑定发送日志订阅总体代码示例 更多相关内容可查看 发布/订阅(Publish/Subscribe) 构建一个简单的…...
【机器学习算法】期望最大化(EM)算法概述
期望最大化(EM)算法是一种迭代算法,用于在有未观测变量的情况下,求解概率模型参数的最大似然估计或最大后验估计。以下是对EM算法的原理与应用进行详细地剖析: EM算法原理 E步 - 期望计算:根据当前估计的模…...
【深度学习】数竹签演示软件系统
往期文章列表: 【YOLO深度学习系列】图像分类、物体检测、实例分割、物体追踪、姿态估计、定向边框检测演示系统【含源码】 【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】 【深度学习】YOLOV8数据标注及模型训练方法整…...
Halcon 多相机统一坐标系
小杨说事-基于Halcon的多相机坐标系统一原理个人理解_多相机标定统一坐标系-CSDN博客 一、概述 最近在搞多相机标定等的相关问题,对于很大的场景,单个相机的视野是不够的,就必须要统一到一个坐标系下,因此我也用了4个相机&#…...
Apache Kylin:大数据分析从入门到精通
一、Kylin简介 Apache Kylin是一个分布式数据分析引擎,专为处理海量数据设计,能够在极短时间内对超大规模数据集进行OLAP(Online Analytical Processing)分析。Kylin通过预计算和高效的查询机制,为用户提供秒级的查询响应时间,支持与Hadoop、Hive、HBase等大数据平台无缝…...
SQL Server 2016导入.bak文件到数据库里面步骤
1、打开SSMS管理器 选择数据库 右键 然后点击还原数据库。 2、选择设备 然后点击三个点 找到本地bak文件,然后点击确定 3、点击确定,会自动弹出来一个成功的提示。...
WPF Frame 简单页面切换示例
原理比较简单,但是有个坑,为了使界面能够正确更新,记得使用 INotifyPropertyChanged 接口来实现属性更改通知。 <Window x:Class"PageTest.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation&…...
kafka-生产者监听器(SpringBoot整合Kafka)
文章目录 1、生产者监听器1.1、创建生产者监听器1.2、创建生产者拦截器1.3、发送消息测试1.4、使用Java代码创建主题分区副本1.5、application.yml配置----v1版1.6、屏蔽 kafka debug 日志 logback.xml1.7、引入spring-kafka依赖1.8、控制台日志 1、生产者监听器 1.1、创建生产…...
3D感知视觉表示与模型分析:深入探究视觉基础模型的三维意识
在深度学习与大规模预训练的推动下,视觉基础模型展现出了令人印象深刻的泛化能力。这些模型不仅能够对任意图像进行分类、分割和生成,而且它们的中间表示对于其他视觉任务,如检测和分割,同样具有强大的零样本能力。然而࿰…...
VS2019+QT5.15调用动态库dll带有命名空间
VS2019QT5.15调用动态库dll带有命名空间 vs创建动态库 参考: QT调用vs2019生成的c动态库-CSDN博客 demo的dll头文件: // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL3_EXPORTS // 符号…...
助力草莓智能自动化采摘,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建果园种植采摘场景下草莓成熟度智能检测识别系统
随着科技的飞速发展,人工智能(AI)技术已经渗透到我们生活的方方面面,从智能家居到自动驾驶,再到医疗健康,其影响力无处不在。然而,当我们把目光转向中国的农业领域时,一个令人惊讶的…...
C++中的生成器模式
目录 生成器模式(Builder Pattern) 实际应用 构建一辆汽车 构建一台计算机 构建一个房子 总结 生成器模式(Builder Pattern) 生成器模式是一种创建型设计模式,它允许你分步骤创建复杂对象。与其他创建型模式不同…...
基于python的PDF文件解析器汇总
基于python的PDF文件解析器汇总 大多数已发表的科学文献目前以 PDF 格式存在,这是一种轻量级、普遍的文件格式,能够保持一致的文本布局和格式。对于人类读者而言, PDF格式的文件内容展示整洁且一致的布局有助于阅读,可以很容易地…...
C++多线程同步总结
C多线程同步总结 关于C多线程同步 一、C11规范下的线程库 1、C11 线程库的基本用法:创建线程、分离线程 #include<iostream> #include<thread> #include<windows.h> using namespace std; void threadProc() {cout<<"this is in t…...
【机器学习】基于CNN-RNN模型的验证码图片识别
1. 引言 1.1. OCR技术研究的背景 1.1.1. OCR技术能够提升互联网体验 随着互联网应用的广泛普及,用户在日常操作中频繁遇到需要输入验证码的场景,无论是在登录、注册、支付还是其他敏感操作中,验证码都扮演着重要角色来确保安全性。然而&am…...
一文读懂Samtec分离式线缆组件选型 | 快速攻略
【摘要/前言】 2023年,全球线缆组件市场规模大致在2100多亿美元。汽车和电信行业是线缆组件最大的两个市场,中国和北美是最大的两个制造地区。有趣的是,特定应用(即定制)和矩形组件是两个最大的产品组。 【Samtec产品…...
批量申请SSL证书如何做到既方便成本又最低
假如您手头拥有1千个域名,并且打算为每一个域名搭建网站,那么在当前的网络环境下,您必须确保这些网站通过https的方式提供服务。这意味着,您将为每一个域名申请SSL证书,以确保网站数据传输的安全性和可信度。那么&…...
Python 设计模式(创建型)
文章目录 抽象工厂模式场景示例 单例模式场景实现方式 工厂方法模式场景示例 简单工厂模式场景示例 建造者模式场景示例 原型模式场景示例 抽象工厂模式 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种将一组相关…...
PyTorch 索引与切片-Tensor基本操作
以如下 tensor a 为例,展示常用的 indxing, slicing 及其他高阶操作 >>> a torch.rand(4,3,28,28) >>> a.shape torch.Size([4, 3, 28, 28])Indexing: 使用索引获取目标对象,[x,x,x,....] >>> a[0].shape torch.Size([3, 2…...
基于MCP协议构建AI与Telegram的智能连接桥梁
1. 项目概述:一个连接AI与即时通讯的桥梁 最近在折腾AI应用开发,特别是想让大语言模型(LLM)能直接操作外部工具,比如发个消息、查个天气。这让我接触到了 Model Context Protocol ,也就是MCP。简单来说&…...
Council框架:构建可编排的智能决策委员会系统
1. 项目概述:从单体应用到分布式决策的演进在软件架构的演进历程中,我们常常面临一个核心挑战:如何将复杂的业务逻辑从臃肿的单体应用中剥离出来,构建出清晰、可维护且具备高内聚、低耦合特性的系统。传统的做法是引入微服务架构&…...
CANN/ops-rand贡献指南
贡献指南 【免费下载链接】ops-rand ops-rand是CANN (Compute Architecture for Neural Networks)算子库中提供的随机数生成库。 项目地址: https://gitcode.com/cann/ops-rand 本项目欢迎广大开发者体验并参与贡献,在参与社区贡献之前…...
CAD2025详细安装教程图文版
一、安装环境建议AutoCAD 2025 建议使用 Windows 10/11 64位系统,电脑配置建议 i5 以上处理器、16GB 以上内存、SSD 固态硬盘,并预留足够磁盘空间。安装前关闭杀毒软件,保持系统组件完整,避免因运行库缺失导致安装失败。二、安装步…...
BlossomLM本地部署指南:开源对话模型从入门到实战
1. 项目概述:一个为本地部署而生的开源对话模型 如果你和我一样,对在本地电脑上运行一个强大、听话且免费的AI助手充满执念,那么BlossomLM这个项目绝对值得你花时间深入了解。它不是来自某个科技巨头,而是一个由个人开发者主导的…...
AI眼底疾病诊断:从图像处理到深度学习的技术融合与实践
1. 项目概述:当AI遇见眼底,一场关于“看见”的革命作为一名在医疗影像和计算机视觉交叉领域摸爬滚打了十多年的从业者,我亲眼见证了技术如何一步步改变诊断的范式。今天想和大家深入聊聊的,是“AI在视网膜疾病诊断中的应用”这个既…...
CANN/sip CgemmBatched算子
HCgemmBatched 【免费下载链接】sip 本项目是CANN提供的一款高效、可靠的高性能信号处理算子加速库,基于华为Ascend AI处理器,专门为信号处理领域而设计。 项目地址: https://gitcode.com/cann/sip 产品支持情况 产品是否支持Atlas 200I/500 A2 …...
GANs生成对抗网络:原理、实现与优化指南
1. GANs基础概念与核心机制生成对抗网络(Generative Adversarial Networks)由Ian Goodfellow在2014年提出,其核心思想是通过两个神经网络相互对抗来生成逼真数据。这个框架包含两个关键组件:生成器(Generatorÿ…...
5大核心技术揭秘:Seraphine如何通过LCU API重塑英雄联盟游戏体验
5大核心技术揭秘:Seraphine如何通过LCU API重塑英雄联盟游戏体验 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine 在竞技游戏的激烈对抗中,信息差往往是决定胜负的关键因素。Seraphine作…...
CANN/ops-fft:FFT算子库
ops-fft 【免费下载链接】ops-fft ops-fft 是 CANN (Compute Architecture for Neural Networks)算子库中提供 FFT 类计算的基础算子库,采用模块化设计,支持灵活的算子开发和管理。 项目地址: https://gitcode.com/cann/ops-fft…...
