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

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变量绑定、拷贝、转移、引用

目录 一&#xff0c;clone、copy 1&#xff0c;基本类型 2&#xff0c;类型的clone特征 3&#xff0c;显式声明结构体的clone特征 4&#xff0c;类型的copy特征 5&#xff0c;显式声明结构体的clone特征 5&#xff0c;变量和字面量的特征 6&#xff0c;特征总结 二&am…...

Java多种方式向图片添加自定义水印、图片转换及webp图片压缩

给个创建水印的示例&#xff1a; /*** 获取水印** 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两个特征&#xff0c;使用窗口time_steps窗口的2个特征&#xff0c;然后预测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&#xff0c;每层的感受野计算过程如下&#xff1a; l 0 1 l_0 1l 0 ​ 1 l 1 1 ( 3 − 1 ) 3 l_1 1…...

百分点科技受邀参加“第五届治理现代化论坛”

11月4日&#xff0c;由北京大学政府管理学院主办的“面向新时代的人才培养——第五届治理现代化论坛”举行&#xff0c;北京大学校党委常委、副校长、教务长王博&#xff0c;政府管理学院院长燕继荣参加开幕式并致辞&#xff0c;百分点科技董事长兼CEO苏萌受邀出席论坛&#xf…...

基于Springboot的智慧食堂设计与实现(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的智慧食堂设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 项…...

「Verilog学习笔记」多功能数据处理器

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 注意题目要求输入信号为有符号数&#xff0c;另外输出信号可能是输入信号的和&#xff0c;所以需要拓展一位&#xff0c;防止溢出。 timescale 1ns/1ns module data_…...

OpenHarmony 4.0 Release 编译异常处理

一、环境配置 编译环境&#xff1a;Ubuntu 20.04 OpenHarmony 软件版本&#xff1a;4.0 Release 设备平台&#xff1a;rk3568 二、下拉代码 参考官网步骤&#xff1a; OpenHarmony 4.0 Release 源码获取 repo init -u https://gitee.com/openharmony/manifest -b OpenHarmo…...

软件测试|MySQL LIKE:深入了解模糊查询

简介 在数据库查询中&#xff0c;模糊查询是一种强大的技术&#xff0c;可以用来搜索与指定模式匹配的数据。MySQL数据库提供了一个灵活而强大的LIKE操作符&#xff0c;使得模糊查询变得简单和高效。本文将详细介绍MySQL中的LIKE操作符以及它的用法&#xff0c;并通过示例演示…...

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)。可以简单的理解为没有权限访问此站&#xff0c;服务器受到请求但拒绝提供服务。 二、HTTP 403 状态码解释大全 403.1 -执行访问禁止。 403.2 -读访问禁止。 403.3 -写访问禁止。 403.4要…...

RAW图像处理软件Capture One 23 Enterprise mac中文版功能特点

Capture One 23 Enterprise mac是一款专业的图像处理软件&#xff0c;旨在为企业用户提供高效、快速和灵活的工作流程。 Capture One 23 Enterprise mac软件的特点和功能 强大的图像编辑工具&#xff1a;Capture One 23 Enterprise提供了一系列强大的图像编辑工具&#xff0c;…...

Linux 进程终止和等待

目录 一&#xff1a;进程常见的退出方法 1. main 函数返回值 2.调用 exit 3.调用 _exit 二&#xff1a;异常问题 三&#xff1a;进程等待 1.概念 2.进程等待的必要性 3.进程等待的方法 <1>&#xff1a;wait --- 系统调用 <2>&#xff1a;waitpid 进程…...

python用tkinter随机数猜数字大小

python用tkinter随机数猜数字大小 没事做&#xff0c;看到好多人用scratch做的猜大小的示例&#xff0c;也用python的tkinter搞一个猜大小的代码玩玩。 猜数字代码 from tkinter import * from random import randint# 定义确定按钮的点击事件 def hit(x,y):global s_Labprint(…...

程序员们保住自己饭碗

在现代社会中&#xff0c;程序员扮演着至关重要的角色。他们不仅仅是编写代码的人&#xff0c;更是保障数字世界安全稳定的守护者。随着科技的迅猛发展&#xff0c;程序员保住自己饭碗的护城河变得愈发重要。本文将探讨程序员如何通过不断学习、技术创新和软实力的发展&#xf…...

顶板事故防治vr实景交互体验提高操作人员安全防护技能水平

建筑业在我国各行业中属危险性较大且事故多发的行业&#xff0c;在建筑业“八大伤害”(高处坠落、坍塌、物体打击、触电、起重伤害、机械伤害、火灾爆炸及其他伤害)事故中&#xff0c;高处坠落事故的发生率最高、危险性极大。工地现场培训vr坠落体验利用虚拟现实技术还原各种情…...

为什么推荐从Linux开始了解IT技术

IT是什么&#xff0c;是干什么的呢&#xff1f; 说起物联网&#xff0c;云计算&#xff0c;大数据&#xff0c;或许大家听过。但是&#xff0c;你知道&#xff0c;像云计算的底层基座是什么呢&#xff1f;就是我们现在说的Linux操作系统。而云计算就是跑在Linux操作系统上的一个…...

【Mysql】增删改查(基础版)

我使用的工具是Data Grip &#xff08;SQLyog Naivact 都行&#xff09; 使用Data Grip创建student表&#xff0c;具体步骤如下&#xff08;熟悉Data Grip或者使用SQLyog&#xff0c;Naivact可以跳过&#xff09; https://blog.csdn.net/m0_67930426/article/details/13429…...

文件夹找不到了怎么恢复?4个正确恢复方法分享!

“我在电脑上保存了很多的文件和文件夹&#xff0c;今天在查找文件时&#xff0c;发现我有一整个文件夹都消失了&#xff0c;不知道怎么才能找到呢。有朋友可以帮帮忙吗&#xff1f;” 电脑中文件夹突然找不到了可能会引发焦虑&#xff0c;尤其是如果这些文件夹包含重要的数据。…...

迅为RK3568开发板GPS模块测试实验步骤

1 首先按照上个实验&#xff0d;串口实验&#xff0c;在设备树中打开串口 9 的节点。 2 然后将 GPS 模块连接好之后&#xff0c;用 U 盘将 GPS 测试程序 gps_test 拷贝到开发板的/mnt 目录下。本小节的测试程序存放路径为“iTOP-3568 开发板\02_ 【iTOP-RK3568 开发板】开发资…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

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

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

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...