rust变量绑定、拷贝、转移、引用
目录
一,clone、copy
1,基本类型
2,类型的clone特征
3,显式声明结构体的clone特征
4,类型的copy特征
5,显式声明结构体的clone特征
5,变量和字面量的特征
6,特征总结
二,变量绑定
1,clone拷贝场景
2,copy拷贝场景
3,所有权转移场景
4,转移的永久性
三,引用
1,对常量的引用
2,对变量的不可变引用
3,对变量的可变引用
5,函数调用
四,引用总结
1,引用的生命周期
2,对字面量的引用
3,对普通变量的引用
4,对引用变量的引用
5,对同一变量的引用
6,链式引用


一,clone、copy
1,基本类型
rust基本类型包括:
- 所有整数类型,比如
u32 - 布尔类型,
bool,它的值是true和false - 所有浮点数类型,比如
f64 - 字符类型,
char
2,类型的clone特征
拥有clone特征的类型:
- 基本类型
- String
- 容器
- 显式声明clone特征的结构体
没有clone特征的类型:
- 没有显式声明clone特征的结构体(结构体默认)
递归决定是否有clone特征的类型:
- 元组,当且仅当其包含的类型都有clone特征的情况下,其自身有clone特征。
3,显式声明结构体的clone特征
前提条件:当且仅当结构体中的成员都具有clone特征的情况下,可以显式声明clone特征。
#[derive(Clone)]
struct S{}#[derive(Clone)]
struct P{a:i32,b:S,
}
4,类型的copy特征
拥有copy特征的类型:
- 基本类型
- 显式声明clone特征的结构体
没有copy特征的类型:
- String
- 容器
- 没有显式声明clone特征的结构体(结构体默认)
递归决定是否有copy特征的类型:
- 元组,当且仅当其包含的类型都有copy特征的情况下,其自身有copy特征。
5,显式声明结构体的clone特征
前提条件:结构体具有clone特征
#[derive(Clone,Copy)]
struct P{a:i32,
}fn main() {let x:P=P{a:5};let y=x;assert_eq!(x.a,5);
}
5,变量和字面量的特征
字面量会自动推导出类型,所以变量和字面量都有唯一确定的类型。
变量和字面量是否具有clone和copy特征,完全取决于其类型是否具有。
6,特征总结
所有类型可以分为3类:
没有clone和copy特征,有clone没有copy特征,有clone和copy特征。
二,变量绑定
1,clone拷贝场景
对于有clone特征的变量或字面量,可以调用clone函数进行拷贝而不转移所有权。
#[derive(Clone)]
struct P{a:i32,
}fn main() {let x:P=P{a:5};let y=x.clone();assert_eq!(x.a,5);
}
2,copy拷贝场景
如果let绑定语句的等号右边是一个有copy特征的变量或字面量,那么这是一个拷贝行为。
let x = 5;let xx = x;assert_eq!(5, x);assert_eq!(6, xx+1);
3,所有权转移场景
如果let绑定语句的等号右边是一个没有copy特征的变量或字面量,那么这是一个所有权转移的行为。
错误代码:
let x = vec![1,2,3];assert_eq!(x[0],1);let y=x;assert_eq!(x[0],1); // 错误
错误原因:y转移走了所有权,不能再使用x
4,转移的永久性
错误代码:
struct P{a:i32,
}
fn main() {let mut x:P=P{a:5};{let y= x;}x.a=6;println!("end");
}
错误原因:y转移了x的所有权之后,x就再也不能用了,即使y的生命周期结束了也一样。
三,引用
1,对常量的引用
fn main() {let x:P=P{a:6};let y= & x;assert_eq!(x.a,6);assert_eq!(y.a,6);assert_eq!((*y).a,6);println!("end");
}
常量只有可读性,原变量x和引用变量y都持有读的能力。
这里y可以直接用,也可以先解引用再用。
2,对变量的不可变引用
正确代码:
struct P{a:i32,
}
fn main() {let mut x:P=P{a:6};let y= &x;assert_eq!(x.a,6);assert_eq!(y.a,6);assert_eq!((*y).a,6);x.a=5;assert_eq!(x.a,5);println!("end");
}
变量x持有读写能力,不可变的引用y只有读能力。
错误代码:
struct P{a:i32,
}
fn main() {let mut x:P=P{a:6};let y= &x;x.a=5;assert_eq!(y.a,5);println!("end");
}
错误原因:在y的读行为结束之前,x不能执行写行为,否则会造成冲突。
同一个变量可以引用多次,也可以对引用变量再进行引用:
struct P{a:i32,
}
fn main() {let mut x:P=P{a:6};let y= &x;let z=&x;let z2=&z;let z3=&z2;let z4=&z3;assert_eq!(x.a,6);assert_eq!(y.a,6);assert_eq!(z.a,6);assert_eq!(z4.a,6);assert_eq!((*z4).a,6);assert_eq!((**z4).a,6);assert_eq!((***z4).a,6);assert_eq!((****z4).a,6);println!("end");
}
这里的z4可以直接读成员,也可以解引用若干次再使用。
3,对变量的可变引用
正确代码:
struct P{a:i32,
}
fn main() {let mut x:P=P{a:6};let y= &mut x;assert_eq!(y.a,6);y.a=5;assert_eq!(x.a,5);println!("end");
}
错误代码:
struct P{a:i32,
}
fn main() {let mut x:P=P{a:6};let y= &mut x;assert_eq!(x.a,6);assert_eq!(y.a,6); println!("end");
}
错误原因:y的读写行为结束之前,x不能执行读行为,否则会造成冲突。
可变引用和不可变引用不能同时存在,否则会造成冲突。
5,函数调用
错误代码:
fn fun(x:Vec<i32>)->i32{x[0]+1
}fn main() {let x = vec![1,2,3];assert_eq!(fun(x),2);assert_eq!(x.len(), 3);println!("end");
}
错误原因:函数调用时转移走了所有权。
正确代码:
fn fun(x:&Vec<i32>)->i32{x[0]+1
}fn main() {let x = vec![1,2,3];assert_eq!(fun(&x),2);assert_eq!(x.len(), 3);println!("end");
}
实现方式:函数入参改成引用类型,传参时也要改成引用。
四,引用总结
1,引用的生命周期
(1)一个引用变量的声明周期只到它的最后一次读写为止
(2)如果声明了引用之后没有读写,那么生命周期直接结束,但是这和直接删除这一句不一样,因为声明引用这一行相当于一次读操作。
(3)如果一个引用变量y被z引用了,且z最后一次读写比y的最后一次读写更晚,那么y的生命周期延长到z的最后一次读写。
PS:如果声明了z是对y的引用之后没有读写,那么声明的这一句就是z的最后一次读操作,这也可能延长y的声明周期。
讨论引用规则时我们默认只讨论一个生命周期之内的引用。
2,对字面量的引用
对字面量的引用,无论是可变引用还有不可变引用,其实都不是引用,而是copy拷贝,讨论引用规则时我们默认不把对字面量的引用这个当做引用。
3,对普通变量的引用
对于普通变量,有mut的是可变变量,没有mut的是不可变变量(常量)。
可变变量可以加可变引用,也可以加不可变引用,不可变变量只能加不可变引用。
4,对引用变量的引用
无论是可变引用变量还是不可变引用变量,都和普通变量一样,可能是可变变量也可能是不可能变量。
对引用变量加引用的规则,和对普通变量一致。
5,对同一变量的引用
对不可变变量不能加可变引用,可以加多个不可变引用。
对可变变量可以加唯一的可变引用,也可以加多个不可变引用。
即,可变引用存在的情况下,只能有一个引用。
6,链式引用
以y是对x的引用,z是对y的引用为例,更长的链的情况应该规则类似。
y的声明周期参考上文“引用的生命周期”。
在所有情况下,z对x的读写能力都和y对x的读写能力相同,因为z一直持有对y的读能力。
(1)x是不可变变量
x和y 一直有读能力,没有写能力
(2)x是可变变量
在y的最后一次读操作或写操作之前,x没有读写能力,之后,x有读写能力
y的能力在声明周期内不变,有读能力,有没有写能力取决于是可变引用还是不可变引用。
五,ref
当我们要引用一个Option的内部成员,可以用ref
struct P{a:i32,
}
struct Node{x:Option<P>,
}
fn main() {let mut p = Node{x:Some(P{a:1})};if let Some(ref mut x)=p.x{x.a=2;}if let Some( x)=p.x{assert_eq!(x.a,2);}println!("end");
}
相关文章:
rust变量绑定、拷贝、转移、引用
目录 一,clone、copy 1,基本类型 2,类型的clone特征 3,显式声明结构体的clone特征 4,类型的copy特征 5,显式声明结构体的clone特征 5,变量和字面量的特征 6,特征总结 二&am…...
Java多种方式向图片添加自定义水印、图片转换及webp图片压缩
给个创建水印的示例: /*** 获取水印** param watermarkText 水印文字* return 水印bufferimage*/public static BufferedImage getWatermark(String watermarkText) {BufferedImage measureBufferdImage new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB…...
基于Pytorch框架的LSTM算法(二)——多维度单步预测
1.项目说明 **选用Close和Low两个特征,使用窗口time_steps窗口的2个特征,然后预测Close这一个特征数据未来一天的数据 当batch_firstTrue,则LSTM的inputs(batch_size,time_steps,input_size) batch_size len(data)-time_steps time_steps 滑动窗口&…...
cnn感受野计算方法
No. Layers Kernel Size Stride 1 Conv1 33 1 2 Pool1 22 2 3 Conv2 33 1 4 Pool2 22 2 5 Conv3 33 1 6 Conv4 33 1 7 Pool3 2*2 2 感受野初始值 l 0 1 l_0 1l 0 1,每层的感受野计算过程如下: l 0 1 l_0 1l 0 1 l 1 1 ( 3 − 1 ) 3 l_1 1…...
百分点科技受邀参加“第五届治理现代化论坛”
11月4日,由北京大学政府管理学院主办的“面向新时代的人才培养——第五届治理现代化论坛”举行,北京大学校党委常委、副校长、教务长王博,政府管理学院院长燕继荣参加开幕式并致辞,百分点科技董事长兼CEO苏萌受邀出席论坛…...
基于Springboot的智慧食堂设计与实现(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的智慧食堂设计与实现(有报告)。Javaee项目,springboot项目。 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 项…...
「Verilog学习笔记」多功能数据处理器
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 分析 注意题目要求输入信号为有符号数,另外输出信号可能是输入信号的和,所以需要拓展一位,防止溢出。 timescale 1ns/1ns module data_…...
OpenHarmony 4.0 Release 编译异常处理
一、环境配置 编译环境:Ubuntu 20.04 OpenHarmony 软件版本:4.0 Release 设备平台:rk3568 二、下拉代码 参考官网步骤: OpenHarmony 4.0 Release 源码获取 repo init -u https://gitee.com/openharmony/manifest -b OpenHarmo…...
软件测试|MySQL LIKE:深入了解模糊查询
简介 在数据库查询中,模糊查询是一种强大的技术,可以用来搜索与指定模式匹配的数据。MySQL数据库提供了一个灵活而强大的LIKE操作符,使得模糊查询变得简单和高效。本文将详细介绍MySQL中的LIKE操作符以及它的用法,并通过示例演示…...
linux防火墙设置
#查看firewall的状态 firewall-cmd --state (systemctl status firewalld.service) #安装 yum install firewalld #启动, systemctl start firewalld (systemctl start firewalld.service) #设置开机启动 systemctl enable firewalld #关闭 systemctl stop firewalld #取消…...
http 403
一、什么是HTTP ERROR 403 403 Forbidden 是HTTP协议中的一个状态码(Status Code)。可以简单的理解为没有权限访问此站,服务器受到请求但拒绝提供服务。 二、HTTP 403 状态码解释大全 403.1 -执行访问禁止。 403.2 -读访问禁止。 403.3 -写访问禁止。 403.4要…...
RAW图像处理软件Capture One 23 Enterprise mac中文版功能特点
Capture One 23 Enterprise mac是一款专业的图像处理软件,旨在为企业用户提供高效、快速和灵活的工作流程。 Capture One 23 Enterprise mac软件的特点和功能 强大的图像编辑工具:Capture One 23 Enterprise提供了一系列强大的图像编辑工具,…...
Linux 进程终止和等待
目录 一:进程常见的退出方法 1. main 函数返回值 2.调用 exit 3.调用 _exit 二:异常问题 三:进程等待 1.概念 2.进程等待的必要性 3.进程等待的方法 <1>:wait --- 系统调用 <2>:waitpid 进程…...
python用tkinter随机数猜数字大小
python用tkinter随机数猜数字大小 没事做,看到好多人用scratch做的猜大小的示例,也用python的tkinter搞一个猜大小的代码玩玩。 猜数字代码 from tkinter import * from random import randint# 定义确定按钮的点击事件 def hit(x,y):global s_Labprint(…...
程序员们保住自己饭碗
在现代社会中,程序员扮演着至关重要的角色。他们不仅仅是编写代码的人,更是保障数字世界安全稳定的守护者。随着科技的迅猛发展,程序员保住自己饭碗的护城河变得愈发重要。本文将探讨程序员如何通过不断学习、技术创新和软实力的发展…...
顶板事故防治vr实景交互体验提高操作人员安全防护技能水平
建筑业在我国各行业中属危险性较大且事故多发的行业,在建筑业“八大伤害”(高处坠落、坍塌、物体打击、触电、起重伤害、机械伤害、火灾爆炸及其他伤害)事故中,高处坠落事故的发生率最高、危险性极大。工地现场培训vr坠落体验利用虚拟现实技术还原各种情…...
为什么推荐从Linux开始了解IT技术
IT是什么,是干什么的呢? 说起物联网,云计算,大数据,或许大家听过。但是,你知道,像云计算的底层基座是什么呢?就是我们现在说的Linux操作系统。而云计算就是跑在Linux操作系统上的一个…...
【Mysql】增删改查(基础版)
我使用的工具是Data Grip (SQLyog Naivact 都行) 使用Data Grip创建student表,具体步骤如下(熟悉Data Grip或者使用SQLyog,Naivact可以跳过) https://blog.csdn.net/m0_67930426/article/details/13429…...
文件夹找不到了怎么恢复?4个正确恢复方法分享!
“我在电脑上保存了很多的文件和文件夹,今天在查找文件时,发现我有一整个文件夹都消失了,不知道怎么才能找到呢。有朋友可以帮帮忙吗?” 电脑中文件夹突然找不到了可能会引发焦虑,尤其是如果这些文件夹包含重要的数据。…...
迅为RK3568开发板GPS模块测试实验步骤
1 首先按照上个实验-串口实验,在设备树中打开串口 9 的节点。 2 然后将 GPS 模块连接好之后,用 U 盘将 GPS 测试程序 gps_test 拷贝到开发板的/mnt 目录下。本小节的测试程序存放路径为“iTOP-3568 开发板\02_ 【iTOP-RK3568 开发板】开发资…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...
Ubantu-Docker配置最新镜像源250605
尝试其他镜像加速器 阿里云镜像加速器:登录阿里云,进入容器镜像服务获取专属加速器地址。毫秒镜像:https://docker.1ms.run。DockerHub镜像加速器:https://docker.xuanyuan.me。Docker Hub 镜像加速服务:https://dock…...
Kafka 消息模式实战:从简单队列到流处理(一)
一、Kafka 简介 ** Kafka 是一种分布式的、基于发布 / 订阅的消息系统,由 LinkedIn 公司开发,并于 2011 年开源,后来成为 Apache 基金会的顶级项目。它最初的设计目标是处理 LinkedIn 公司的海量数据,如用户活动跟踪、消息传递和…...
