004、变量与可变性

news2025/1/18 6:31:35

1. 变量与可变性

        在Rust中,变量默认是不可变的,这一设计是为了让你安全方便地写出复杂、甚至是并行的代码。

        当然,Rust也提供了可使用的可变变量的方法,这个待会讨论。

        当一个变量是不可变时,一旦它被绑定到某个值上面,这个值就再也无法被改变。下面是一段错误的演示代码:

fn main() {
    let x = 5;
    println!("x的值为:{x}");
    
    x = 10;
    println!("x的值为:{x}");
}

        使用 cargo run 命令运行代码后发现报错了。红线处报错内容的中文意思是:不能为不可变变量分配两次。

        Rust的编译器能够保证那些声明为不可变的值一定不会发生变化,意味着你不需要去跟踪一个变量会如何变化, 这样的好处就是代码逻辑更好理解和推导。

        接下来我们讲一下如何使变量可变,很简单,就是在变量名之前加个 mut 关键字就行了。给变量加了这个关键字就表示,接下来的代码或者其它代码可能会改变这个变量的值。

        所以,要使上面的错误代码正确运行,只需要在第一次声明变量 x 的时候在名称前加上一个 mut 关键字就行了,像下面这样:

fn main() {
    let mut x = 5;
    println!("x的值为:{x}");

    x = 10;
    println!("x的值为:{x}");
}

        修改后的代码运行结果如下:

        关于可变变量,这里再补充一点。

        除了避免出现bug,设计一个变量的可变性还需要考虑其他因素。比如,当你在使用某些重型数据结构时,适当地使用可变性去修改一个实例,可能比赋值和重新返回一个新分配的实例更有效率。

        当数据结构较为轻小时,采用偏向于函数式的风格,通过创建新变量来进行赋值,可能会使代码可读性更高。在类似这样的情境下,损失少许性能也许是值得的。

2. 变量与常量之间的区别

         在Rust中,也有常量的概念,它和不可变变量的特性一样,绑定到常量上的值无法被其他代码修改,但两者的区别肯定是有的。

        首先,不能用 mut 关键字来修饰一个常量。因为常量不仅是默认不可变,而且总是不可变。

        其次,声明一个常量用的是 const 关键字而不是 let,而且在声明的同时你必须显式地标注出值的类型。关于数据类型,我们下篇文章马上会讲到。现在你只需要记住一点:常量总是需要标注类型的。

        再次,常量可以在任何作用域中声明,甚至包括全局作用域。这在一个值需要被不同部分的代码共同引用时十分有用。

        最后,你只能将常量绑定到一个常量表达式上,而无法将一个函数的返回值,或其它需要在运行时计算的值绑定到常量上。

        下面举一个声明常量的例子:

const MAX_POINTS: u32 = 100_000;

        代码中,我们使用 const 关键字声明了一个变量 MAX_POINTS,指定类型为 u32,即:无符号的32位整数。

        这个常量的名称我是全大写然后中间用下划线连接,这个是Rust中约定俗成的,不是强制性的,而变量、函数名是全小写然后中间下划线连接,都是为了提高代码的可读性。当然,你也可以使用其它命名法,比如驼峰式。

        然后它的值是 100_000,就是 一百万的意思。这个中间的下划线也是为了提高代码可读性,你可以理解为千分位分隔符。

3. 隐藏

        隐藏(Shadow),是 Rust 中的一个概念,即:一个新声明的变量可以覆盖掉旧的同名变量,用 Rust 的说法就是:第一个变量被第二个新变量隐藏(Shadow)了。

        这意味着后面我们使用这个变量时,它指向的是新变量了。当然,我们可以重复使用 let 关键字并使用相同的变量名称来不断隐藏之前的变量。

        代码举例:

fn main() {
    let x = 5;
    let x = 5 + 1;
    let x = x * 2;

    println!("x的最终值为:{x}");
}

        运行结果如下图所示,虽然我们得到了12,但是出现了代码提示和警告。

        代码提示:help: if this is intentional, prefix it with an underscore: `_x`,中文意思是,帮助:如果这是故意的,请在它前面加一个下划线:`_x` 。

        这个 `_x`  是什么意思呢?在Rust中,下划线_是一个特殊的标识符,被称为 “下划线” 或 “忽略” 模式匹配。它通常用于在模式匹配中忽略某个变量。

        由于我们多次覆盖变量x的值,所以触发了这个提示。当你看到这个提示时,它是在告诉你,如果你故意想忽略一个变量或值,你可以使用下划线作为前缀。

        warning: `variables` (bin "variables") generated 1 warning (run `cargo fix --bin "variables"` to apply 1 suggestion)

        这个警告的中文意思是,`variables'(bin“variables”)生成1个警告(运行`cargo fix--bin“variable”`应用1个建议)。这表明虽然你的代码能够成功编译并运行,但有一些潜在的问题或不推荐的做法,比如,未使用的变量、未使用的导入、过时的 API 使用等。这些警告通常会建议你采取一些行动来改进你的改码。

        若要解决这个问题,你可以按照警告信息的建议,运行 cargo fix 命令。这个命令会自动应用Rust编译器提供的建议来修复源代码中的一些问题。我们来运行试一下:

cargo fix --bin "variables"

        当然,如果你的黑窗口已经在项目目录下,可以只要写 cargo fix 就行了。 

        在Rust中,cargo fix 是一个非常有用的命令,它可以帮助开发者自动修复编译器中的警告。从 Rust 1.29 版本开始,cargo fix 作为子命令被加入到 cargo 工具中。

        当你运行cargo fix时,它会分析你的代码并尝试自动修复那些编译器发出警告的问题。这些问题可能包括代码风格问题、潜在的错误和不推荐的用法等。cargo fix 尝试使用最新的修复方法来解决这些问题,使你的代码更符合最佳实践和官方推荐的代码风格。

        例如,假设你的代码中存在一些未使用的变量或导入,这可能会导致编译警告。运行 cargo fix 后,它会尝试自动删除这些未使用的变量或导入,从而消除警告。

        关于隐藏我们再来举个例子,示例代码如下:

fn main() {
    let spaces = "    ";
    let spaces = spaces.len();
    println!("spaces的值为:{}", spaces);
}

        这段代码能正常运行,是因为 spaces 在第一次声明时是字符串类型,而第二次声明的 spaces 虽然名称和第一次一样,但是它表示的是第一个 spaces 的长度,是一个数值变量。

        隐藏机制允许我们复用变量名称,而不需要做出区分。如果我们去掉第二次声明的代码中的 let 关键字会怎样?就会出现下面的报错内容。

        因此,如果要覆盖之前的变量,一定是带着 let 关键字哦 ~ 

4. 结语

        下一篇文章,将详细向你介绍Rust中的 数据类型,前面遇到的 u32,你就会知道是什么意思啦 ~

        由于能力有限、本人也还在学习摸索阶段,文中难免有错漏之处,若有读者大大发现,欢迎在评论区留言。

        最后,码字不易,即便只有一个赞也可以让我动力满满,感谢你的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1345225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows下配置GCC(MinGW)环境

一、下载并安装MinGW 步骤1:下载MinGW安装器 前往MinGW的官方下载源,通过以下链接可以获取到最新版的MinGW安装程序: 网页地址:https://sourceforge.net/projects/mingw/files/ [MinGW 下载地址](https://sourceforge.net/proj…

计算机组成原理-总线概述

文章目录 总线简图总线的物理实现总览总线定义总线的特性总线的分类按数据格式分类串行总线并行总线 按总线功能分类注意系统总线的进一步分类 总线的结构单总线的机构双总线的结构三总线的结构四总线的结构 小结 总线简图 总线的物理实现 如果该为数据总线,那么当…

快来检测一下你是否真的学会了C语言,保证你看完后收获满满!!

文章目录 每日一言1234567891011121314151617181920结语 每日一言 人生而自由,却无往不在枷锁中。 --社会契约论 1 以下程序段的输出结果是? char s[]"\\141\141abc\t"; printf("%d\n",strlen(s));A. 9 B. 12 C. 13 D. 14 正确答…

华为发布的工业软件三大难题:适用于CAD领域的NURBS裁剪曲面自交快速检测

以下内容转载: 自相交,在几何图形有效性验证中的一个错误类型,面要素的自相交在原始数据中是最常见的,这种错误有些可以人工发现,但有些就需要借助程序来发现。 发生自相交的根本原因情况比较多,有些是因为…

LOAM: Lidar Odometry and Mapping in Real-time 论文阅读

论文链接 LOAM: Lidar Odometry and Mapping in Real-time 0. Abstract 提出了一种使用二维激光雷达在6自由度运动中的距离测量进行即时测距和建图的方法 距离测量是在不同的时间接收到的,并且运动估计中的误差可能导致生成的点云的错误配准 本文的方法在不需要高…

第七课:计算机网络、互联网及万维网(WWW)

第七课:计算机网络、互联网及万维网(WWW) 第二十八章:计算机网络1、局域网 Local Area Networks - LAN2、媒体访问控制地址 Media Access Control address - MAC3、载波侦听多路访问 Carrier Sense Multiple Access - CSMA4、指数…

Rust开发⼲货集(1)--迭代器与消费器

本内容是对 Rust开发干货集[1] 的实践与扩展. iter() 不转移所有权 先简单解释下什么叫"转移所有权": 在 Rust 中,"转移所有权"(Ownership Transfer)是一种核心概念,它涉及变量和数据的所有权从一个实体转移…

C/C++ BM3 链表中的节点每k个一组翻转

文章目录 前言题目思路阐述代码总结 前言 这道题的关键是理解链表指针的位置; 在BM2的区间翻转基础上,多了个指针偏移,博客里面我贴图阐述一下。 题目 思路阐述 这道题的翻转过程参考BM2的题解,这里主要阐述一下指针移动和整体思…

redhat 8 安装openstack

redhat 8 安装openstack 1、安装文档2、redhat 8 安装openstack3、使用openstack 1、安装文档 openstack官方安装文档 https://docs.openstack.org/install-guide/ 2、redhat 8 安装openstack 3、使用openstack

【C/C++笔试练习】sort排序、STL容器、vector的特性、一级容器、迭代器失效、异常捕获、动态转换、统计每个月兔子的总数、字符串通配符

文章目录 C/C笔试练习选择部分(1)sort是不稳定排序(2)存放即有序的STL容器(3)连续储存的STL容器(4)vector的特性(5)一级容器(6)unorde…

2、gdb常用功能2

1.4、线程 程序避免不了涉及到多线程.常用指令如下. 命令简写形式说明info thread显示当前进程内所有线程信息thread 切换到num线程thread find 寻找regexp在gdb中的idinfo address 结合上述图片理解,第一列的id是gdb内部为线程排序的一个id,第三列中…

Redis:原理速成+项目实战——Redis的Java客户端

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成项目实战——Redis常见命令(数据结构、常见命令总结) 📚订阅专栏&…

算法基础之最短编辑距离

最短编辑距离 核心思想 : 线性dp 集合定义 : f[i][j]为操作方式的最小值 集合计算 : 三种操作 取最小 ① 删除 : 将a[i]删掉 使ab相同 –> f[i-1][j] 1 f[i][j]② 增添 : 在a[i]后加上一个数 使ab相同 –> f[i][j-1] 1 f[i][j]③ 替换 : 将a[…

【unity学习笔记】捏人+眨眼效果+口型效果

一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型(.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。(VRM-0.116.0_0f6c) 3.将univrm导入到工程中(assets)。 三…

基于FPGA的数字电路(PWM脉宽调制)

一.PWM的制作原理 假如我们有一个锯齿波,然后在锯齿波上设置一个阈值(黑色水平虚线),凡是大于该阈值时输出均为高电平,反之则为低电平,这样我们是不是就得到一个PWM信号呢?如果我们想调整它的占…

数据治理:释放数据价值的关键

随着数字化时代的到来,数据已成为组织和企业最重要的资产之一。然而,数据的快速增长和复杂性也给数据管理带来了巨大的挑战。为了确保数据的质量、安全性和合规性,数据治理已成为组织和企业必须面对的重要问题。数据治理是数据要素市场建设的…

OSG绘制视锥体(升级版)

OSG绘制视锥体&#xff0c;这一篇增加设置相机参数接口&#xff0c;支持通过eye、center、up设置相机参数。 代码如下&#xff1a; #include "stdafx.h" #include <osgViewer/Viewer> #include <osg/ShapeDrawable> #include <osg/Geode> #includ…

SkyWalking UI 修改发布Nginx

文章目录 SkyWalking UI修改图标修改路由发布到Nginx添加认证修改路由模式vite.config.ts添加baseNginx配置 SkyWalking UI skywalking-booster-ui下载地址 修改图标 替换 logo.svg 修改路由 router - data - index.ts 发布到Nginx 添加认证 # 安装 yum install -y h…

电子学会C/C++编程等级考试2022年12月(八级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:生理周期(2022.12) 人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。例如,智力周期的高峰,人会思维敏捷,精力容…

【网络安全常用术语解读】SCAP详解

本文主要介绍什么是SCAP&#xff0c;SCAP的产生背景是怎样的&#xff0c;SCAP有什么用途&#xff0c;有哪些组件&#xff0c;各个组件的用途是什么&#xff1f; SCAP产生背景 由于计算机和网络技术的快速发展&#xff0c;越来越多的软件和系统被应用到企业和机构中&#xff0c…